Неожиданное поведение IntentService - PullRequest
5 голосов
/ 06 мая 2010

Я использовал IntentService в своем коде вместо Service, потому что IntentService создает для меня поток в onHandleIntent (намерение Intent), поэтому мне не нужно сам создавать Thead в коде моей службы.

Я ожидал, что два намерения одного и того же IntentSerivce будут выполняться параллельно, поскольку в IntentService для каждого изобретения создается поток. Но мой код показал, что два намерения выполняются последовательно.

Это мой код IntentService:

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.");
        }
    }
}

А код звонка в сервис ниже:

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);

    }
}

Я видел это сообщение в журнале:

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

Журнал показывает, что второе намерение ожидало завершения первого намерения, и они находятся в одном потоке.

Это там что-то, что я неправильно понял из IntentService. Чтобы два намерения службы выполнялись параллельно, нужно ли заменить IntentService службой и самому запустить поток в коде службы?

Спасибо.

Ответы [ 5 ]

9 голосов
/ 19 мая 2010

Целевая очередь - это весь смысл использования IntentService.

7 голосов
/ 02 августа 2010

Все запросы к IntentService обрабатываются в одном рабочем потоке, и одновременно обрабатывается только один запрос. Если вы хотите выполнять две задачи параллельно, я думаю, что вам нужно использовать Service и создавать потоки для каждой задачи после запуска Service.

Что касается AsyncTask, существует пул потоков для обработки всех задач. Если номер вашей задачи превышает размер пула потоков, некоторые из этих AsyncTasks должны будут ждать, пока поток из пула не станет доступным. Однако размер пула потоков изменяется в разных версиях платформы.

Вот мой результат теста:

  • Android 2.2: размер пула потоков = 5
  • Android 1.5: размер пула потоков = 1
6 голосов
/ 07 мая 2010

Насколько я знаю, IntentService имеет один поток-обработчик, и каждый намеренный очереди в этом потоке. Когда все намерения в очереди сделаны, служба завершается. Он не создает независимых потоков для каждого намерения. Я не знаю ни одного подкласса Service, который работает так, как вы описываете, вам, вероятно, придется написать свой собственный.

1 голос
/ 01 июня 2010

Я думаю, что вы хотите AsyncTask, а не Service или IntentService. Или вы всегда можете просто выстрелить с бедра, определив такой способ бега:

Runnable runnable = new Runnable() {

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

... для каждой из ваших задач. Честно говоря, это может быть проще, чем иметь дело с этими вспомогательными классами Android.

0 голосов
/ 17 марта 2011

Вот пример использования Сервиса вместо IntentService, он может служить вашей цели. http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...