Android Thread Constructs
Service
|
Thread
|
IntentService
|
AsyncTask
| |
---|---|---|---|---|
When to use ? | Task with no UI, but shouldn't be too long. Use threads within service for long tasks. | - Long task in general. - For tasks in parallel use Multiple threads (traditional mechanisms) | - Long task usually with no communication to main thread. (Update)- If communication is required, can use main thread handler or broadcast intents[3] - When callbacks are needed (Intent triggered tasks). | - Long task having to communicate with main thread. - For tasks in parallel use multiple instances OR Executor [1] |
Trigger | Call to method onStartService() | Thread start() method | Intent | Call to method execute() |
Triggered From (thread) | Any thread | Any Thread | Main Thread (Intent is received on main thread and then worker thread is spawed) | Main Thread |
Runs On (thread) | Main Thread | Its own thread | Separate worker thread | Worker thread. However, Main thread methods may be invoked in between to publish progress. |
Limitations / Drawbacks | May block main thread | - Manual thread management - Code may become difficult to read | - Cannot run tasks in parallel. - Multiple intents are queued on the same worker thread. | - one instance can only be executed once (hence cannot run in a loop) [2] - Must be created and executed from the Main thread |
[1] API Level 11 (Android 3.0) introduces the executeOnExecutor() method, that runs multiple tasks on a thread pool managed by AsyncTask. Below API Level 11, we need to create multiple instances of AsyncTask and call execute() on them in order to start parallel execution of multiple tasks.
[2] Once you create an object of an AsyncTask and call execute, you cannot call execute on that object again. Hence, trying to run an AsyncTask inside a loop will require you to each time create a new object in the loop before calling the execute on it.
To be very precise, you cannot do something like :
TestAsyncTask myATask = new TestAsyncTask();
for (int i = 0; i < count; i++) {
myATask.execute("one", "two", "three", "four");
}
But you can do :
TestAsyncTask myATask = new TestAsyncTask();
myATask.execute("one", "two", "three", "four");
}
[3] Thanks to comment posted by Mark Murphy (@commonsguy) : "there's nothing stopping an IntentService from communicating back to activities. A broadcast Intent is good for that, particularly with setPackage() to keep it constrained to your app (available on Android 2.1, IIRC). An ordered broadcast can be particularly useful, as you can rig it up such that if none of your activities are on-screen, that some manifest-registered BroadcastReceiver picks up the broadcast and raises a Notification."
留言
張貼留言