IntentService使用详解

介绍

在Android中可以通过Service和IntentService创建服务:

Service

这是适用于所有服务的基类。扩展此类时,必须创建一个用于执行所有服务工作的新线程,因为默认情况下,服务将使用应用的主线程,这会降低应用正在运行的所有 Activity 的性能。

IntentService

这是 Service 的子类,它使用工作线程逐一处理所有启动请求。如果您不要求服务同时处理多个请求,这是最好的选择。 您只需实现 onHandleIntent() 方法即可,该方法会接收每个启动请求的 Intent,使您能够执行后台工作。

IntentService的优点:

  • 创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent,所以不需要我们再单独的创建线程。
  • 传递到IntentService中的任务是逐一执行的,所以不需要担心出现多线程问题
  • 执行完所有任务后自动停止服务,不需要调用stopSelf()。

由此可见,使用 IntentService 类实现服务也许是最好的选择,IntentService的使用流程和Service一样,但它只需要实现onHandleIntent()方法,下面看一个IntentService的使用示例:

使用示例

  1. 创建服务
public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        for (int i = 0; i < 10; i++) {
            Log.e("===","第"+i);
            try {
                Thread.sleep(1*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("===","服务自动结束");
    }
}

这个服务只是在onHandleIntent方法中模拟了一个10秒倒计时并且打印了数字,并且在onDestroy()中打印了“服务自动结束”
2. 注册服务

<service android:name=".MyIntentService"/>

3 启动服务

startService(new Intent(MainActivity.this,MyIntentService.class));

打印结果:

05-14 21:46:30.711 11817-11895/com.example.wangc.myapplication E/===: 第0
05-14 21:46:31.714 11817-11895/com.example.wangc.myapplication E/===: 第1
05-14 21:46:32.716 11817-11895/com.example.wangc.myapplication E/===: 第2
05-14 21:46:33.718 11817-11895/com.example.wangc.myapplication E/===: 第3
05-14 21:46:34.720 11817-11895/com.example.wangc.myapplication E/===: 第4
05-14 21:46:35.722 11817-11895/com.example.wangc.myapplication E/===: 第5
05-14 21:46:36.724 11817-11895/com.example.wangc.myapplication E/===: 第6
05-14 21:46:37.725 11817-11895/com.example.wangc.myapplication E/===: 第7
05-14 21:46:38.726 11817-11895/com.example.wangc.myapplication E/===: 第8
05-14 21:46:39.727 11817-11895/com.example.wangc.myapplication E/===: 第9
05-14 21:46:40.731 11817-11817/com.example.wangc.myapplication E/===: 服务自动结束

从上面这个简单的示例可以看到两点
一,并没有在onHandleIntent()方法中去创建新的线程执行任务;
二,在任务执行完成后并没有手动调用stopself()方法。
这两点都可以从接下来的源码分析中找到答案,先看下它的源码

源码分析


public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

去掉注释之后的源码就上面这点,根据它的工作流程分析:

首先在onCreate()方法中创建了一个HandlerThread(其实就是一个带有Looper的线程),然后启动这个线程,并且拿到线程的Looper对象。再传给ServiceHandler这个内部类。所以这里就解释了前面的问题,为什么不需要再自己创建工作线程,因为它内部已经帮我们创建好了。

onStartCommand()执行服务,它内部调用onStart()方法,onStart()方法内部创建Message,并通过ServiceHandler发送出去。

ServiceHandler处理在onStart()方法中发送的消息。在handleMessage()方法中先调用onHandleIntent()方法,我们要处理的具体业务逻辑就放在这个方法内。最后调用stopSelf(msg.arg1)结束服务;这也就是为什么我们不需要自己手动调用stopself()方法。

最后在onDestroy()方法中调用mServiceLooper.quit()退出Looper。

总结

在大多数时候都可以使用IntentService因为它使用更简单,我们只需要实现onHandleIntent()方法,并且不需要去主动停止服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值