tags:

views:

757

answers:

4

I used IntentService in my code instead of Service because IntentService creates a thread for me in onHandleIntent(Intent intent), so I don't have to create a Thead myself in the code of my service.

I expected that two intents to the same IntentSerivce will execute in parallel because a thread is generated in IntentService for each invent. But my code turned out that the two intents executed in sequential way.

This is my IntentService code:

public class UpdateService extends IntentService {

    public static final String TAG = "HelloTestIntentService";

    public UpdateService() {
        super("News UpdateService");
    }

    protected void onHandleIntent(Intent intent) {

        String userAction = intent
        .getStringExtra("userAction");

        Log.v(TAG, "" + new Date() + ", In onHandleIntent for userAction = " + userAction + ", thread id = " + Thread.currentThread().getId());

        if ("1".equals(userAction)) {
            try {
                Thread.sleep(20 * 1000);
            } catch (InterruptedException e) {
                Log.e(TAG, "error", e);
            }

            Log.v(TAG, "" + new Date() + ", This thread is waked up.");
        }
    }
}

And the code call the service is below:

public class HelloTest extends Activity {

    //@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        Intent selectIntent = new Intent(this, UpdateService.class);
        selectIntent.putExtra("userAction",
                "1");

        this.startService(selectIntent);

        selectIntent = new Intent(this, UpdateService.class);
        selectIntent.putExtra("userAction",
                "2");

        this.startService(selectIntent);

    }
}

I saw this log message in the log:

V/HelloTestIntentService(  848): Wed May 05 14:59:37 PDT 2010, In onHandleIntent for userAction = 1, thread id = 8
D/dalvikvm(  609): GC freed 941 objects / 55672 bytes in 99ms
V/HelloTestIntentService(  848): Wed May 05 15:00:00 PDT 2010, This thread is waked up.
V/HelloTestIntentService(  848): Wed May 05 15:00:00 PDT 2010, In onHandleIntent for userAction = 2, thread id = 8
I/ActivityManager(  568): Stopping service: com.example.android/.UpdateService

The log shows that the second intent waited the first intent to finish and they are in the same thread.

It there anything I misunderstood of IntentService. To make two service intents execute in parallel, do I have to replace IntentService with service and start a thread myself in the service code?

Thanks.

+1  A: 

As far as I know, The IntentService has one handler thread, and each intent queues in that thread. When all queued intents are done, the service exits. It does not create independent threads per intent. I don't know of any Service subclasses that work the way you are describing, you'd probably have to write your own.

Matt
The design pattern of IntentService is a work queue that guarantees that the requests are queued and not processed in parallel. As pointed out below, you can fire off an AsyncTask for each parallel work. Make certain that your service code is reentrant.
mobibob
+1  A: 

The intent queuing is the whole point of using IntentService.

Eno
A: 

I think what you want is an AsyncTask rather than either a Service or an IntentService. Or you could always just shoot from the hip by defining a runnable like this:

Runnable runnable = new Runnable() {

    public void run() {
        ....
    }
};
new Thread(runnable).start();

... for each of your tasks. Honestly, that may be easier than dealing this these Android helper classes.

Pneuma
+2  A: 

All requests to IntentService are handled on a single worker thread, and only one request will be processed at a time. If you want to do two tasks in parallel, I think you need to use Service and create threads for each task after Service starts.

As for AsyncTask, there's a thread pool for handling all of the tasks. If your task number exceeds thread pool size, some of these AsyncTasks will need to wait until a thread from the pool becomes available. However, the thread pool size changes in different platform versions.

Here's my test result: Android 2.2: thread pool size = 5 Androdi 1.5: thread pool size = 1

miaomiao