Android进阶2:线程和线程池(3)—— IntentService原理解析

IntentService也是属于Android异步线程模块的一部分,上一篇是HandlerThread的源码:
Android进阶2:线程和线程池(2)—— HandlerThread原理解析
如果对HandlerThread原理不太熟悉的,建议先看下我的上一篇文章HandlerThread的原理解析,因为IntentService内部使用的是HandlerThread。。。

先来看下IntentService的用法:

需求: 实现一个IntentService实现类,定义一个成员变量count, 开启线程,回调给UI主线程,
代码如下:

/**
 * Created by ${liumengqiang} on 2018/8/2.
 */

public class TestIntentService extends IntentService {

    private int count = 0;

    private boolean isRunning = true;

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

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        while(isRunning) {
            synchronized (this) {
                if(count >= 10) {
                    isRunning = false;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count ++;
                //发送广播
                Intent intentBroadcast = new Intent();
                intentBroadcast.putExtra("count", count+ "");
                intentBroadcast.setAction("edu.jju.broadcastreceiver");
                sendBroadcast(intentBroadcast);//发送普通广播
            }
        }
    }
}

MainActivity代码:

    public class TestBrodecast extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String countString = intent.getStringExtra("count");
            textView.setText(countString);
        }
    }

以上是IntentService的简单例子,接下来就看源码= -= ;

IntentService源码解析

1: 成员变量

 private volatile Looper mServiceLooper; //Looper对象
    private volatile ServiceHandler mServiceHandler; //运行在子线程的handler
    private String mName; //工作线程的名称
    private boolean mRedelivery; //服务销毁是是否重新创建,以及创建之后的状态。

从成员变量看出了:

  • 有Looper对象
  • 有handler对象
  • mRedelivery对象?

前两个我们能嗅到handler的气息,但是这个mRedelivery是什么鬼? 是这样的,现在只能说是跟服务的销毁和重建有关。下文解释。

2: onCreate方法:
既然是IntentService,service的子类,肯定还是从onCreate方法说起:

    @Override
    public void onCreate() {
        //注意点1:
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.
        super.onCreate();
        //注意点2:创建HandlerThread
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start(); //开启HandlerThread

        mServiceLooper = thread.getLooper(); //获取子线程的Looper对象
        mServiceHandler = new ServiceHandler(mServiceLooper); //实例化运行在子线程的handler
    }

上述源码写了两个注意点:

  1. 上文Google给出的描述大致意思是:会启动一个子工作线程,并且通过静态启动服务(startService方法),此时将切换到子工作线程
  2. 注意2主要是之后的四行代码,可以看到,首先创建了HandlerThread对象,通过上篇博客知道了handlerThread也就是handler + Thread的封装,在这里使用HandlerThread说明:IntentService内部实际上原理使用的还是HandlerThread, 只不过此时的载体是Service。

通过上述代码可以看出,创建了HandlerThread, 再开启子线程,记住,此时子线程已经开启了,只不过还没有消息能够处理。通过上篇博客我们知道了其实mServiceHandler 是运行在子线程的。那么就有必要看下mServiceHandler的源码:

    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); //任务完成,精确的销毁service
        }
    }

通过源码可以看书,ServiceHandler的内部逻辑很简单,就是先调用了onHandleIntent方法,等等?这个方法不就是我们开发者必须复写的方法嘛,因为ServiceHandler就是运行在子线程,所以onHandleIntent肯定也是在子线程啦,所以我们可以在onHandleIntent方法内做耗时操作。

通过onCreate方法描述,知道了必须通过startService启动服务,那么startService启动服务的流程,各位应该还记得吧?

3:startService启动服务

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId); //每次启动都会调用onStart方法
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage(); //新建消息对象
        msg.arg1 = startId; //用于销毁service任务
        msg.obj = intent; //传入Intent对象
        mServiceHandler.sendMessage(msg); //发送消息
    }

通过上述源码可以看出:调用onStartCommand每一次都会首先调用onStart方法,那么在onStart方法内,看到了Message,sendMessage发送消息是不是很熟悉了,然后在ServiceHandler的handleMessage方法中回调给开发者。

流程通了吧,在捋一下:

onCreate: 通过HandlerThread开启一个子线程,在子线程中运行的ServiceHandler中回调onHandleIntent方法交给开发者处理
onStart:在此方法内发送消息给子线程。

通过HandlerThread和IntentService的学习,我们知道内部根本的原理就是:handler, Looper, MessageQueue + Thread,所以通过在HandlerThread对象单一的情况下,无论发送多少的任务,都是顺序执行的,不会并发执行

文中如有错误,欢迎指出,一边纠正 = - = 。

Android开发交流群:543671130
这里写图片描述

猜你喜欢

转载自blog.csdn.net/lmq121210/article/details/81366222