13

Somewhere in the application, I need to get a localized string using the getString method for an error message. For this, I need a Context instance, gotten from for example an Activity. Is this really how this is designed? Am I really forced to pass around these objects into classes and methods or am I missing the point and is there some other way to get a string reference?

To clarify, in an Activity I have an inner AsyncTask subclass that in doInBackground instantiates a new class for some short network processing outside the UI thread. I want error messages to be localized and for that I need to pass in a Context instance (in other words, the Activity) into that class. The design of getting value resources from the XML files just seems to be a bit unintuitive. It makes me wonder why this is so coupled together with Context instances and not something static or - forgive me - a singleton, as Context implies to be the global application context and not just a part of it like an Activity.

dodehoekspiegel
  • 329
  • 2
  • 12
  • 2
    Is this happening in an utility class or something? You do need context for `getString()`, so the short answer is yes. If you provide more details on where/how you need to call this, there may be a *better way* than passing/holding a method parameter. – Paul Burke Nov 08 '12 at 21:56

2 Answers2

7

No, you should not do this. A simple rule is; if what you need the context for is touching the UI or is only associated with the internals of the activity class, then you should use the activity context. Even then, it is important that any reference to the context does not have a lifetime which is greater than that of the activity.

The big danger of not following this is that you pass out a reference to the activity context to somewhere deeper in your code and your activity is destroyed whilst the reference you are holding is still in scope. You just leaked your activity and everything it has a reference to. I would recommend not passing the activity context outside the activity unless truly essential and even then, be very sure to control that life time.

So, it the context is needed for something which is not UI related, such as your need to get a string resource, then use the application context. Inside an activity, and where the string reference is declared in the activity, then using the activity context would be acceptable and in my opinion, preferred as you are making a conscious decision regarding scope and life time.

That said, you should ask whether this particular method is better placed in an activity. It may well not be but do ask yourself.

Finally, a small pedantic point. You do not pass objects anywhere. You pass a reference, in fact a value of a reference to the object. Everything in Java is passed by value.

Simon
  • 14,407
  • 8
  • 46
  • 61
  • 1
    I don't need the Context object for UI related tasks, just for getString so making Application available via something like a State class instead seems to be the way to go. All the hate for globally available state (i.e. singletons) just points me in an uglier direction - passing around references. And yes, I know that in Java you pass around copies of references to objects instead of deep-copying them. – dodehoekspiegel Nov 08 '12 at 22:26
  • 1
    Just use getApplicationContext(), See this for a great discussion on application context. http://stackoverflow.com/questions/5018545/getapplication-vs-getapplicationcontext BTW, your application is a singleton so the haters can hate all they like but everything they do depends on singletons :) Yes, plenty of ways to abuse that but using application context is not one of them and since it's a singleton, state doesn't come into it. Your application instance IS state. – Simon Nov 08 '12 at 22:35
0

You could always extend the application class. Make a static method on there for getInstace() to get the context.

user123321
  • 12,593
  • 11
  • 52
  • 63