Did I mention I'm still learning Android? Here are some things I wrestled with getting started.
I had a background job I needed to run in this application, and I wanted to display progress as it worked. I saw several possible solutions:
- An Activity with a Java Thread
- An Activity with an Android AsyncTask
- A Service with a Java Thread
- An Intent Service
I didn't know about Intent Services when I started, and because I needed to update the UI based on feedback from the worker thread, I started with AsyncTask. I really struggled with using AsyncTask because it lacks good separation of concerns. Your background code is stuck in the same class as your UI update code. Not very nice.
I also wanted to have my background code in a class that had no Android framework dependencies. Just a pojo. That made it even more difficult.
The problem was resolved when I realized that the work I needed to do in the background was best thought of as a service. AsyncTask seems to be really just for small, but long-running foreground tasks. You use AsyncTask to keep from blocking the main thread in those cases.
An AsyncTask class looks like this:
AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object... arg0) {
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
}
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
}
};
The "onWhatever" methods get called by the framework on the main UI thread, while the doInBackground runs in a separate worker thread when you start the task.
I then went down the plain android.app.Service path. Extending service works fine, but you have to manage the service life cycle, and things like threading and re-entrance, yourself.
android.app.IntentService relieves you of that burden. All you have to do is:
public class FooService extends IntentService {
public FooService() {
super("FooService");
}
public FooService(String name) {
super(name);
}
@Override
protected void onHandleIntent(Intent intent) {
}
}
onHandleIntent will execute in a background thread. To start the service (from an activity):
startService(new Intent(this, FooService.class));
Of course, the irony is that the UI is not currently getting updates from the service! It will in a future release, though. And I'm still extending a framework class. I'll be taking another this whole thing again soon.