IntentService 使用及原理浅析

概述

IntentService适用于执行单次的异步的耗时操作,用完会自动销毁服务,本质上是Service内部封装了HandlerThread的异步消息处理机制,理解了HandlerThread的原理才能理解IntentService
关于HandlerThread的介绍:HandlerThread的使用及原理浅析

使用

首先创建一个IntentService的实现类,在其中模拟耗时操作:

public class TestIntentService extends IntentService {

    public TestIntentService() {
    //传入的线程名字
        super("TestIntentService");
    }
    //必须实现的处理方法,该方法在子线程执行
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        try {
            Log.d("test","当前的执行线程为 "+Thread.currentThread().getName());
            //模拟耗时操作
            Log.d("test","开始耗时操作");
            Thread.sleep(1000);
            Log.d("test","结束耗时操作");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
    //IntentService销毁时调用
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("test","异步任务结束");
    }
}

比如在Activity中进行调用:

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

当然可以在 Intent中传递一些必要的数据,这里省略了。
运行观察控制台输出:

08-02 16:43:21.282 11381-11474/com.franky.test D/test: 当前的执行线程为 IntentService[TestIntentService]
08-02 16:43:21.283 11381-11474/com.franky.test D/test: 开始耗时操作
08-02 16:43:22.283 11381-11474/com.franky.test D/test: 结束耗时操作
08-02 16:43:22.285 11381-11381/com.franky.test D/test: 异步任务结束

可以清晰地看到任务是在子线程执行的,并且任务执行完毕后,IntentService自动销毁。

原理

IntentService的代码比较简单,贴出整个实现:

public abstract class IntentService extends Service {
    //子线程的Looper
    private volatile Looper mServiceLooper;
    //消息处理使用的Handler
    private volatile ServiceHandler mServiceHandler;
    //线程名
    private String mName;
    //Service如果没处理完任务之前被杀死,设置为true,那么Service恢复后
    //将处理最后一个传进来的Intent
    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;//传递的线程名字
    }

    //Service如果没处理完任务之前被杀死,设置为true,那么Service恢复后
    //将处理最后一个传进来的Intent,fasle的话不会恢复最后的Intent
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //首先创建一个HandlerThread对象
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        //获取HandlerThread的Looper,该Looper工作在子线程
        mServiceLooper = thread.getLooper();
        //使用这个Looper来创建Handler,所以handleMessage同样工作在子线程
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    //onStartCommand中调用了该方法
    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        //生成一个Message对象
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        //封装好intent
        msg.obj = intent;
        //发送Message
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        //这里调用onStart方法
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();//结束子线程的Looper
    }


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

     //该方法工作在子线程,但是同一个IntentService对象,在多处调用startService方法启
     //动的时候,该方法只能一次处理一个Intent的请求,其他请求暂停,直到所有Intent的请求
     //执行完毕后,InentService才会停止。
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);

整个的调用流程如下:

  1. 启动服务:startService;
  2. IntentService调用onCreate()方法创建HandlerThread对象,和Handler对象;
  3. IntentService调用onStart()方法,创建Message对象并使用Handler发送;
  4. Looper机制取出Message分发给Handler;
  5. Handler调用handleMessage()方法,回调onHandleIntent()方法;
  6. onHandleIntent()执行完毕,调用stopSelf()结束服务;

总结

IntentServiec通过Service包装HandlerThread机制,使其具有异步消息处理的能力,其实对于IntentServiec主要还是要理解HandlerThread的处理机制。

猜你喜欢

转载自blog.csdn.net/franky814/article/details/81389866