views:

71

answers:

1

I have a singleton which stores some prudent information about the user of my application. At the moment, it stores the user's login and the user's location.

1) The location is found via a Service. At the moment, the Service references my singleton directly to stuff the longitude and latitude into it. I would like to use a BroadcastReceiver to send a broadcast that the singleton hears and uses to update the values, instead.

However, to register the BroadcastReceiver, I need a Context in my singleton. What is the slickest way to achieve what I'm wanting. Is BroadcastReceiver possibly not the appropriate object?

2) Also, what problems am I looking at with using a singleton? I assume that Android will possibly reclaim this memory at any given time (which would obviously be bad); so how can I prevent that? Would passing in the application's Context and storing it in a member variable thwart this?

The Android documentation states: "But, the life cycle of a static is not well under your control; so to abide by the life-cycle model, the application class should initiate and tear down these static objects in the onCreate() and onTerminate() methods of the Application Class," but I'm not entirely sure how to accomplish this.

+1  A: 

However, to register the BroadcastReceiver, I need a Context in my singleton. What is the slickest way to achieve what I'm wanting. Is BroadcastReceiver possibly not the appropriate > object?

The "slickest way" is to not do what you are doing. Please only register a BroadcastReceiver from an Activity, Service, or maybe an Application. You must unregister this BroadcastReceiver when the Activity, Service, or Application is destroyed.

I assume that Android will possibly reclaim this memory at any given time (which would obviously be bad); so how can I prevent that?

You don't. Android reserves the right to terminate your process at any time (e.g., to reclaim memory). Task killers on Android 2.1 and previous will terminate your process at any time. Once all components of your application are destroyed, Android may recycle your process at any time, clearing out your heap at the same time. And so on.

Only put things in memory that you don't mind losing.

It is best to think of your "application" as a basket of loosely-coupled components, not as a monolithic entity.

Would passing in the application's Context and storing it in a member variable thwart this?

No.

The Android documentation states: "But, the life cycle of a static is not well under your control; so to abide by the life-cycle model, the application class should initiate and tear down these static objects in the onCreate() and onTerminate() methods of the Application Class," but I'm not entirely sure how to accomplish this.

Create a subclass of Application and indicate in the manifest that Android should use it, via the android:name attribute on the <application> element.

CommonsWare
Thanks for your input. How would you recommend "carrying around": this information? Are you suggesting reading it from a database every time it (suppose "it" is login information to pass with a web service) is needed?
Andrew
Yes, store it in a database or in the `SharedPreferences`
Falmarri
Would you recommend, then, keeping my singleton with the member variables holding login information and creating a method in the singleton to retrieve them, which either returns the value asked for or, if it is not set (ie: the singleton was destroyed and recreated), read from the database, set and returned?
Andrew
Why are you rolling your own singleton instead of using a service?
Falmarri
I'm pretty new to Android development. I know Services avoid being reclaimed; so is this how people avoid the issue? Is it frowned upon?
Andrew
@Andrew: "How would you recommend "carrying around": this information? Are you suggesting reading it from a database every time it...is needed?" -- a database is certainly a possibility. I am not saying your singleton is wrong. I am saying that your singleton trying to register a `BroadcastReceiver` is wrong. I am also saying that your singleton will go bye-bye, so you better have that data stored somewhere else and be in position to lazy-load it. Think of the singleton as a cache, not as the Rock of Gibraltar.
CommonsWare
All right well I think I'll do this: I'll subclass Application and instantiate my singleton there. I'll have member vars for what I need and wrapper get/sets around them. The set will update the member var and write to db. The get will pull from heap if the member var is populated or read from the database if not. Thanks for your help
Andrew
Though I shall need to pass a ContentResolver so it can make the ContentProvider call, right?
Andrew
@Andrew: It looks like `getContentResolver()` is available on `Application`, though I have not tried it.
CommonsWare