Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Singleton which is used between Activity and Service

im wondering if it would be a bad idea to create a Singleton that is used between some Android Activities and a Android Service. As far as I know the static fields, in my case the Singleton, is available as long as the whole Process is alive.

My plan is to use a singleton instead of Parcelable to share data between my activities and a Background service. So my Activity1 will add some data by calling MySingleton.getInstance().addData(foo); then I would sent an Intent to inform my Service that new Data has been added to the singleton. Next my BackgroundService would handle the intent and call MySingleton.getInstance().getLatestData(); then it would process the data (takes some time). The result of the service would next be "post" back by using the singleton and fire a broadcast intent, which are handled by the Activity1 (if alive) and the Activity1 will retrieve the result from the singleton.

Do you guys think thats a bad idea?

EDIT: What I want to implement is an peace of software that downloads data from a web server parse it and return the result. So my Activity would create DownloadJob Object. The DownloadJob-Object would be put into the DownloadScheduler (Singleton) which queues and manage all DownloadJobs. The DownloadScheduler would allow to run 5 DownloadJobs at the same time and use a queue to store the waiting. The effective Download would be done by the DownloadService (IntentService), which gets informed over an Intent that the a new DownloadJob should now be executed (downloaded) right now. The DowanlodService would retrieve the next job from the DownloadSchedulers queue (PriorityBlockingQueue) and return the Result by setting DownloadJob.setResult(...) and fires up an broadcast intent, that the Result is ready, which will be received by the DownloadScheduler which would remve the job from the queue and inform the Activity that the download is complete etc.

So in my scenario I would use the singleton to access the DownloadJobs from the DownloadService instead of making a DownloadJob Parcelable and pass it with the Intent. So i would avoid the problem, that I have two DownloadJobs in memory (one on the "Activity Site" and one on "Service site").

Any suggestions how to solve this better?

Is it true that static instances, like DownloadScheduler(Singleton), would be used by freed by the android system on low memory? So would subclassing the Application and hold there the reference (non static) avoid this problem?

like image 997
sockeqwe Avatar asked Nov 22 '12 19:11

sockeqwe


People also ask

Is Android service a singleton?

Finally, Service in Android is a singleton. There is only one instance of each service in the system.

Should a service be a singleton?

3 Answers. Show activity on this post. IMHO yes, services should not hold state and should therefore be made singleton.

Where do we use singleton class in Android?

The Singleton Pattern is a software design pattern that restricts the instantiation of a class to just “one” instance. It is used in Android Applications when an item needs to be created just once and used across the board. The main reason for this is that repeatedly creating these objects, uses up system resources.


2 Answers

If you are using the singleton just as shared memory between a background service which I assume is performing operations on a different thread, you may run into synchronization issues and or read inconsistent data.

If the data in the singleton is not synchronized, you have to be careful because you are relying on your "protocol" to be sure that nobody is reading while your background thread is writing (which may lead to errors).

On the other hand, if it is synchronized, you are risking to face anr error because the activity which reads the data may be blocked waiting the service to finish to write the data in the singleton.

As the other said, you also have to keep in mind that your singleton may be freed if the os needs resources, and that your data may not be there anymore.

I'd rather use an event bus such as otto or eventbus

EDIT:

Using a singleton as the entry point of background (intent) service is the approach suggested in 2010 Virgil Dobjanschi talk about building rest client applications for android.

The suggested approach is having a singleton that performs as controller of ongoing requests. Please consider also that request to intent service are already queued by the os, so you can throw several intents that will be processed sequentially by the intent service.

Some time ago I also tried take that as a starting point for a library, which still remains unfinished. YOu can find the sources here

What I would certainly not do is to store your data in the singleton. The approach I would prefer is to store the data in some persistent storage (such as sql / preferences / file / content provider) and let the client know of the change through a broadcast message (or, if you are using a content provider, through an observer).

Finally, to some extent this is the approach followed by the robospice library, which looks quite mature and ships a lot of interesting features such as caching.

like image 78
fedepaol Avatar answered Oct 20 '22 15:10

fedepaol


A better idea is to subclass Application and put any long living objects in there. By subclassing Application you can properly handle startup and shutdown of the application something you can't easily do with a singleton. Also by using an Application Activites and Services can share access to the models within your program without resorting to parcelables. And you can avoid all of the problems Singletons bring to your program.

You also don't have to resort to storing everything in a database which requires lots of boiler plate code just to shove a bunch of data in there. It doesn't do anything for sharing behavior between parts of your application and doesn't do anything to facilitate communication and centralization of activities. If you really need to persist state between shutdowns great use it, but if not you can save yourself a lot of work.

You could also look into using something like Roboguice which makes injecting shared models into your Activities and services.

You might find this helpful:

what's design pattern principle in the Android development?

like image 26
chubbsondubs Avatar answered Oct 20 '22 16:10

chubbsondubs