Android Service详解(三)---IntentService

作者: SuperBig 发布时间: 2019-09-12 浏览: 3661 次 编辑

这是第三篇文章主要讲的是IntentService的使用


一、Service的耗时操作如何解决呢?


不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的。所以,如果你的Service将要运行非常耗时或者可能被阻塞的操作时,你的应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,你应该在Service中重新启动一个新的线程来进行这些操作。现有两种方法大家参考:


① 直接在Service的onStartCommand()方法中新建一个线程来执行;


② Android SDK 中为我们提供了一个现成的Service类来实现这个功能,它就是IntentService,它主要负责以下几个方面:

Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread.

    生成一个默认的且与主线程互相独立的工作者线程来执行所有传送至 onStartCommand() 方法的Intetnt

Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.

    生成一个工作队列来传送Intent对象给你的onHandleIntent()方法,同一时刻只传送一个Intent对象,这样一来,你就不必担心多线程的问题。

Stops the service after all start requests have been handled, so you never have to call stopSelf().

    在所有的请求(Intent)都被执行完以后会自动停止服务,所以,你不需要自己去调用stopSelf()方法来停止该服务

Provides default implementation of onBind() that returns null.

    提供了一个onBind()方法的默认实现,它返回null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation

    提供了一个onStartCommand()方法的默认实现,它将Intent先传送至工作队列,然后从工作队列中每次取出一个传送至onHandleIntent()方法,在该方法中对Intent对相应的处理;


思路就是

    IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程。

这里就给我们提供了一个思路,如果有耗时的操作可以在Service里面开启新线程,也可以使用IntentService来处理耗时操作。 但你若是想在Service中让多个线程并发的话,就得使用第一种方法,在Service内部起多个线程,但是这样的话,你可要处理好线程的同步。

也就是说,如果只是需要有一个线程的话那么我们使用IntentService是很方便的,如果需要处理多个线程并发的话那只能使用第一种方法。第一种方法写在我的上篇博客当中Android Service详解(一)---概述和StartService


二、如何创建一个IntentService呢?

1.还是以Android Studio为环境,非常的方便




可以将这个勾选取消





这样会自动生成一个IntentService,但是你发现整个代码很乱,你可以把这些去掉只留下关键的方法就可以,我只留下了构造方法和onHandleIntent方法。

2.修改代码,在onHandleIntent方法种实现业务方法,例如

@Override
protected void onHandleIntent(Intent intent) {
    Log.e(TAG, intent.getStringExtra("info"));
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("info", "传递数据");
startService(intent);
 
 
    for(int i = 0;i<20;i++){
        Log.e(TAG, "onHandleIntent-" + i);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.在Mainactivity种修改

Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("info", "传递数据");
startService(intent);


4.当IntentService全部执行完后将自动停止


可以看出在启动这个intentService后再次点击则会在上个耗时操作完成后继续执行(队列的方式),并且在所有操作执行后自动销毁。并且不会阻塞主线程

通常使用该IntentService完成本App内部的耗时操作

至此IntentService的基本使用方法就结束了十分的简单实用

那么最后附上:源码


Android Service详解系列

1,Android Service详解(一)---概述4,Android Service详解(四)---绑定服务BoundService详解之扩展Binder类7,Android Service详解(七)---绑定服务BoundService详解之Messenger双向通信的实现
2,Android Service详解(二)---StartService5,Android Service详解(五)---绑定服务BoundService详解之AIDL的使用8,Android Service详解(八)---前台服务详解
3,Android Service详解(三)---IntentService6,Android Service详解(六)---绑定服务BoundService详解之AIDL的自定义属性使用


————————————————

原文链接:https://blog.csdn.net/superbiglw/article/details/53126101