【问题标题】:Unexpected behavior of IntentServiceIntentService 的意外行为
【发布时间】:2010-05-05 22:14:29
【问题描述】:

我在我的代码中使用了 IntentService 而不是 Service,因为 IntentService 在 onHandleIntent(Intent intent) 中为我创建了一个线程,所以我不必在我的服务代码中自己创建一个 Thead。

我预计同一个 IntentSerivce 的两个意图将并行执行,因为在 IntentService 中为每个 invent 生成一个线程。但我的代码证明这两个意图是按顺序执行的。

这是我的 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 替换为服务并在服务代码中自己启动一个线程?

谢谢。

【问题讨论】:

    标签: android


    【解决方案1】:

    intent queuing 是使用 IntentService 的重点。

    【讨论】:

      【解决方案2】:

      对 IntentService 的所有请求都在单个工作线程上处理,并且一次只会处理一个请求。如果要并行执行两个任务,我认为您需要使用 Service 并在 Service 启动后为每个任务创建线程。

      对于 AsyncTask,有一个线程池来处理所有的任务。如果您的任务数量超过线程池大小,则其中一些 AsyncTask 将需要等待池中的线程可用。但是,不同平台版本的线程池大小会有所不同。

      这是我的测试结果:

      • Android 2.2:线程池大小 = 5
      • Android 1.5:线程池大小 = 1

      【讨论】:

      • 感谢您的简短解释。真的有帮助
      【解决方案3】:

      据我所知,IntentService 有一个处理程序线程,每个意图都在该线程中排队。当所有排队的意图都完成后,服务退出。它不会为每个意图创建独立的线程。我不知道任何按您描述的方式工作的 Service 子类,您可能必须自己编写。

      【讨论】:

      • IntentService 的设计模式是一个工作队列,保证请求是排队的,而不是并行处理的。正如下面所指出的,您可以为每个并行工作触发一个 AsyncTask。确保您的服务代码是可重入的。
      【解决方案4】:

      我认为您想要的是 AsyncTask,而不是 Service 或 IntentService。或者,您总是可以通过定义这样的 runnable 来从臀部射击:

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

      ...为您的每项任务。老实说,这可能比处理这些 Android 帮助类更容易。

      【讨论】:

      • 我会在 Runnable 上使用 AsyncTask ——绝对有助于前/后处理并将结果返回给 UI 线程。如果有什么东西可以持续超过 Activity 的生命周期,那么使用 IntentService 是最好的选择。
      • AsyncTask 很好,但应该在 Service 中使用,您应该始终牢记 Android 生命周期:活动在配置更改期间被销毁并重新创建...... AsyncTask 将失去对 Activity 的引用和可能会被摧毁......
      【解决方案5】:

      这是一个使用 Service 而不是 IntentService 的示例,它可能符合您的目的。 http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService

      【讨论】:

        猜你喜欢
        • 2020-10-04
        • 2016-07-16
        • 2016-05-10
        • 2020-07-23
        • 2021-08-23
        • 2021-11-16
        • 2017-10-20
        • 2016-06-29
        • 2015-07-31
        相关资源
        最近更新 更多