Android开发Android源码分析Android技术知识

Android源码系列二:HandlerThread和Inten

2019-05-27  本文已影响5人  Taonce

在分析了 Handler源码 之后,我们紧接着加入了相关联的 HandlerThreadIntentService 的源码剖析。

HandlerThread

它是 Thread 的子类,并且自带 Looper 光环

  1. 如何使用:
        // 创建 HandlerThread 对象
        val handlerThread = HandlerThread("mainActivity")
        handlerThread.start()
        // 获取 HandlerThread 中的 Looper 对象
        val myLooper: Looper = handlerThread.looper
        val handler = object : Handler(myLooper) {
            override fun handleMessage(msg: Message?) {
                // 运行在 HandlerThread 线程中
                super.handleMessage(msg)
                Log.d("taonce", "handleMessage thread is: ${Thread.currentThread().name}")
                Log.d("taonce", "handleMessage msg is: ${msg?.arg1}")
            }
        }
        val message: Message = handler.obtainMessage()
        message.arg1 = 0x11
        // 主线程中发送消息
        handler.sendMessage(message)
        thread {
            val msg: Message = handler.obtainMessage()
            msg.arg1 = 0x01
            // 子线程中发送消息
            handler.sendMessage(msg)
        }
        
    // Log:
    // handleMessage thread is: mainActivity
    // handleMessage msg is: 17
    // handleMessage thread is: mainActivity
    // handleMessage msg is: 1
    
    通过 Log 可以发现,无论我们在子线程中还是主线程中发送消息,handlerMessage(msg) 都是运行在 handlerThread 中。而且,将 handlerThread 中的 Looper 传递给 handler 后,handler 也不需要再进行 Looper.prepare()Looper.loop() 的执行过程了,最终 handlerhandleMessage(msg: Message?) 也会在 handlerThread 中进行。
    也就是说:HandlerThread 开启了一个线程来实现多线程效果,但是它处理多任务是按照串行执行。
  2. 源码简析:
    @Override
    public void run() {
        mTid = Process.myTid(); 
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
    
    源码的 run() 方法中就是把我们在子线程中需要做的默认做了一遍,以免造成在子线程中使用 Handler.sendMessage(msg: Message?) 造成 No Looper 的异常。

IntentService

  1. 如何使用:

    class MyIntentService : IntentService("") {
        override fun onHandleIntent(intent: Intent?) {
        // 让此线程休眠一会
         Thread.sleep(60 * 1000 * 1000)
        }
    
        override fun onStart(intent: Intent?, startId: Int) {
         super.onStart(intent, startId)
      }
    
        override fun onCreate() {
            super.onCreate()
     }
    }
    

    在我们使用 Service 的时候,都知道 Service 是运行在主线程中,不可以做耗时操作,但是我们在 IntentServiceonHandleIntent(intent: Intent?) 将线程休眠都没有出现ANR,是不是很疑惑,下面我们就看看 IntentService 的源码是怎么处理的。

  2. 源码简析:

    // 我将一些未参与分析的源码都给删除了,只保留了和 HandlerThread 相关的
    public abstract class IntentService extends Service {
        // HandlerThread 中的 Looper 对象
        private volatile Looper mServiceLooper;
        // Handler 对象
        private volatile ServiceHandler mServiceHandler;
    
    
        private final class ServiceHandler extends Handler {
            public ServiceHandler(Looper looper) {
                super(looper);
            }
    
            @Override
            public void handleMessage(Message msg) {
                // 将子线程的处理交给抽象方法:onHandleIntent(@Nullable Intent intent)
                onHandleIntent((Intent)msg.obj);
                stopSelf(msg.arg1);
            }
        }
    
        @Override
        public void onCreate() {
    
            super.onCreate();
            // 创建 HandlerThread 对象,并开启此线程
            HandlerThread thread = new HandlerThread("IntentService[" + mName +     "]");
            thread.start();
            // 获取子线程中的 Looper 对象
            mServiceLooper = thread.getLooper();
            // 将 Looper 传递给 ServiceHandler
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }
        
            @Override
        public void onStart(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            // 发送消息,然后在 handleMessage(Message msg) 处理
            mServiceHandler.sendMessage(msg);
        }
        
        @WorkerThread
        protected abstract void onHandleIntent(@Nullable Intent intent);
    }
    

    IntentService 的源码中,我们主要看三点:

    • mServiceLooper 变量,它是一个 Looper 对象
    • mServiceHandler 变量,它继承了 Handler
    • threadonCreate() 方法中的局部变量,是一个 HandlerThread 变量

    我们开始一步一步分析:在 onCreate() 中,创建了 thread 变量,并且获取到 looper ,传递给 mServiceHandler 对象,保证 serviceHandlerhandleMessage(Message msg) 在新开的线程中执行任务。

    onStart() 中,利用 mServiceHandler 发送一个 msg , 当 IntentService 执行到这的时候,mServiceHandler 就开始调用 handlerMessage(Message msg) ,我们看到在这里面,源码是直接调用了抽象方法 onHandlerIntent() 方法,这个方法会在我们自定义的 IntentService 中进行重写,也就可以进行耗时操作了。

    HandlerThreadIntentService 的源码在知晓 Handler 分发消息原理后很容易就理解,如果你在上面的分析中发现了不足或者认为不正确的地方,欢迎留言指正或者扫描下方的二维码联系我本人沟通交流,谢谢!

    扫描关注
上一篇 下一篇

猜你喜欢

热点阅读