I have a two part question. Both are somewhat general.
I'm creating an app that relies heavily on communication with a server. I plan to have different classes for each repository I'll need. Is an Android service the correct pattern to use here? There may be certain situations where I'll want to cache things between activities. Will a service allow me to do this?
Assuming a service is what I want to use for this, how can I load content once the service is bound. When the user opens the app, I want to start loading content. However, binding a service isn't blocking, so I can't write the code that makes requests with the service in my onStart() right? Is there some helper class that will wait for the service to load then execute a function? I know I could put some code in my onServiceConnected() method but I'd like to stay away from coupling like that.
Hopefully that wasn't too abstract. Thanks in advance.
Yes, Service is the way to go, but a started service, not a bound one.
You could make async request methods, and the Service can broadcast the result back to your Activity.
The async request in this case is a startService(intent) with an
Intent containing the request parameters. The service would start a background thread for the operation, optimally you can use a networking library for this (for example Volley).
And the reply is a broadcast by the Service with the relevant data.
This answers the problem of caching, because the Service can decide what to return. So in case the Service does not have the requested resource, it will download (and return) it. But if the Service has the resource, then it will just simply return the cached version.
To start, you should get yourself familiar with these topics:
Started Services (for the requests)
LocalBroadcastReceiver (for the reply)
Event Bus (alternative to LocalBroadcastReceiver, for example Otto)
I don't know much about your concrete needs, but it seems like you want to implement a REST client with cache. There is a really good Google IO presentation on that here. Definately worth to watch!
1)If you need code to run even when your Activity isn't, the correct answer is a Service. If you just need to cache data, then storing it in a global static variable somewhere may be ok.
2)Your service can start a Thread or AsyncTask. These execute in parallel. onStartCommand generally launches it in this case.
As with most things, the answer to these questions are subjective at best. I would need more information then I currently have, but I'll take a vague, general stab at this...
If you need something persistently hitting your server repeatedly I would say use a service.
Where you call it is not nearly as important as how many times it needs to be called. That being said the answer is yes. If you need this data as soon as the application or activity loads, then the onCreate method is where it needs to be loaded.
My reccomendation is either A) service or B)AsyncTask.
Go with A if you have to hit the server repeatedly for data and need it in regular intervals. Otherwise go with an AsyncTask and load all the data you need into an object for storage. Then you can use it as you need and it will essentially be "cached".
The difference between the two is simply "best tool for the job". I see you use some javascript. To give a proper analogy, using a service for a server call rather than an async task, is the equivalent of using a web socket (node js) when you could of just used an ajax call. Hope this helps. Oh and PS, please don't use static variables in Android =).
Related
I've read by many people to not use AsyncTask for web requests, but rather use IntentService, since AsyncTask is bound the lifecycle of its activity. is that always the case? cause I'm making a social media app, And I wonder if each action the user makes should launch a service (for example, press like, add comment, etc)?
Do not use AsyncTask, as you may have read, it is problematic on Activity recreate. However, you may use AsyncTaskLoader with LoaderManager, which is designed to fix the problem.
And there is one point you are wrong with IntentService, you do not launch a service everytime using IntentService. You are submitting requests to the same service only (unless it is being killed), and the IntentService pull requests from the stack.
I tend to use a mixture of both. I use an IntentService when requesting/posting data from a server, then deserialising it and storing it locally. All this could take several seconds depending on the amount of data returned and the server's response time.
I would use an AsyncTask within an activity if I know that the request is going to be very quick. I use it for more fire and forget small tasks.
The important thing to bear in mind is that your AsyncTask is tied to your activity. And if your activity gets destroyed (due to an orientation change etc.) then you could easily have an NPE in the onPostExecute().
If the task you wish to perform is specific to a Context and is considered garbage once you leave the Context, such as if you consider the user session to be invalid once they leave, then an AsyncTask is a good choice.
However, if the task is specific to a context and may take a long time to perform and you want the user to be able to leave and come back later to see the result, a service may be well suited even though the task is specific to a Context.
If the task you wish to perform is applicable outside the scope of a Context, then a service may be better suitable.
If you just always use a service, you'll probably be over complicating your code.
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?
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.
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?
Using a singleton like this is not necessarily a bad idea, but you will lose it's state if Android decides to stop your process. You may want to consider storing your state instead in a SQLite database or a persistent queue (take a look at tape for a good example).
I'm currently learning to develop for Android and I'm having a somewhat hard time figuring out when and how to use services. I have already seen the numerous questions asked about very similar things, but I can't quite find the exact answer to my questions.
I have an app which talks to a restful api. I fetch several lists which I would like to cache in memory and only update if the user hits a refresh button, or certain activities are created. If a list is refreshed, sometimes several activities need to be notified, so that they update their content (if they are on screen at the time). I store the data I retrieve in value objects.
On a non-android app I would usually create a sort of dataproxy class in a singleton pattern. I could ask the dataproxy to update its data via http request, and then it would send some kind of system-wide notification as soon as the data is changed, so the interested views can all be updated. I hope this makes sense.
My question is now: How do I do this the android way? Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data? Should I do my non-persistent caching in this service or somewhere else? Do I need AIDL, or can I just use normal objects for moving data between a service and an activity? Although I find the android dev guide pretty well written and useful, I haven't found much information on services best practice.
Thank you in advance!
How do I do this the android way?
You assume that there is a single "android way".
Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data?
You can either bind, or send commands via startService().
Should I do my non-persistent caching in this service or somewhere else?
If you're sure that you only want it to be in RAM, I'd lean towards static data members. Make the service be the "do-er", not the store.
That being said, I'd treat this more as a synchronization pattern, with the real store being a database or directory, with a cache in RAM. Users will find this less frustrating -- under your current plan, if they are in your app, then take a phone call for a while, they'll have to have you download all the data again.
Do I need AIDL, or can I just use normal objects for moving data between a service and an activity?
If they are all in the same process, normal objects is fine via binding, or use Intent extras for the command pattern.
Now, back to:
How do I do this the android way?
Option #1: Wrap your store in a ContentProvider and use ContentObserver for changes.
Option #2: Have your service send a broadcast to your package when the data changes, so the foreground activity can find out about the change via a BroadcastReceiver registered via registerReceiver(). Other activities simply grab a fresh look at the data in onResume() -- the only one that immediately needs to know of the data change is the one the user is interacting with, if any.
Option #3: Use the binding pattern with the service, and have the foreground activity register a listener with the service. The service calls the listener when data is updated. Once again, ather activities simply grab a fresh look at the data in onResume()
Option #4: Cook up your own listener system as part of your static data members, being very very careful to avoid memory leaks (e.g., static reference to an activity or service that is destroyed, preventing its garbage collection).
There are probably other options, but this should get you started.
The Google IO session mentioned by Andrew Halloran:
http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
Check out the Google I/O session videos. I implemented REST api calls the easy BUT wrong way. It wasn't until watching this Google I/O video that I understood where I went wrong. It's not as simple as putting together an AsyncTask with a HttpUrlConnection get/put call.
I want to better understand how to structure an Android app where an activity fires off an API call (for example).
I'd currently implement it by putting the API call into an AsyncTask subclass, passing it a reference to the activity so it can update the UI in onPostExecute. But my gut-feel is that this is creating overly-coupled code.
I'm wondering whether instead I should put an API call like that into a service, and use a BroadcastReceiver to update the activity.
What say you, AsyncTask, or BroadcastReceiver?
I usually follow the Local Service pattern. I have a strong suspicion that this is how the official Twitter app works and that this is the pattern most of the Google apps use. This also solves the issue of your app going away (getting killed or going into the background) before the task finishes, or if the phone switches configuration during a background task.
BroadcastReceiver and service is an overhead here. A request to web-service should not go to long. Service is appropriate in case of downloading files or something similar.
AsyncTask way is the right one here. But I would suggest you showing a progress dialog to let user know that your application isn't freezed, but doing some useful work.
See the example here.
AsyncTask is just fine. Only thing you should worry about is referencing you Activity using WeakReference to avoid whole Activity be memory leaked. It isn't overly-coupled code imo if you using observer or events patterns.
I would go with a service only if the call is going to take long, so that the user can leave the app while it's completing.
I'd use the AsyncTask if the task is short enough that it almost wouldn't go ANR if done in UI thread.
(disclaimer: I consider myself a beginner, and I'm expecting comments from more experienced people)
Here's scenario:
Client makes remote call to the service (returns void) and provides
a callback object
Service executes some long running logic on the background thread
and then uses callback object to trigger ether success or failure
which (since these manipulate visual elements) execute in
Activity#runOnUiThread block
The scenario runs fine. The question is - can I use AsyncTask to make
code less verbose (how?) and would be there any advantages in doing it
that way?
Or should I just get away from client callbacks alltogether and
execute remote service calls retrofitted to return some value within
AsyncTask#doInBackground?
It is difficult to say whether AsyncTask will make things less verbose, since we don't know the verbosity of your current implementation.
For me, AsyncTask means I don't have to worry about cleaning up threads myself (e.g., post some sort of kill job to a LinkedBlockingQueue my background thread is waiting on). It also eliminates the custom Job classes I used to create for using with LinkedBlockingQueues. And, it simplifies a bit doing final work back on the UI thread.
In your case, with a remote service, the UI thread issue is less critical, since the activity needs to handle that itself.
I don't see what the difference is between your #2 and your last paragraph. In both cases, your service will call the callback object, which will use something like runOnUiThread() to arrange for the work to be done on the UI thread.
AFAIK, the only two ways to have a service doing any sort of asynchronous work let the client know that work is done is by a broadcast Intent or a callback object. Broadcast Intents are convenient but public (i.e., other code can watch for them).
I suspect I probably have not helped much here, but I just don't know enough of your scenario to provide greater detail.
I'm having quite the same question : i'm developping a map activity, with a 'lazy-loading' functionnality (xml from Network, parsing it, then updating my map with the 'items' created from that parsing...)
i wondered what would be 'the best' way to implement it...
async service launched from a thread, an update notification via Intent?
just a thread (no service, since i don't need to expose it to other applications) w/ callback
asyncTask with callback
i'm comparingthese in terms of speed, using the Android SDK performance analysis Tool traceview
I guess a more precise answer might be found from Android contributors on the Android-developper-group...