美文网首页
唠唠 HandlerThread 和 IntentService

唠唠 HandlerThread 和 IntentService

作者: 枫叶栈 | 来源:发表于2017-12-01 10:11 被阅读0次

    一、概述

    HandlerThread 看名字,应该包含Handler和Thread,然而,你以为你以为的就是你以为的?哈哈。 开个玩笑,言归正传。 HandlerThread 继承自Thread,自身包含一个Looper。或许你该问,既然没有Handler相关的东西,为什么交HandlerThread。其实这个跟Android的Handler工作机制相关,Handler对象的生成是需要在有Looper的线程中,如果在没有Looper的线程中生成Handler对象,将会爆出异常。

    IntentService 是一个继承自Service的类,他内部实现原理是依赖HandlerThread来实现的,IntentService启动了一个后台服务,在该后台服务中启动一个线程来工作,当线程工作完后,自动的安全关闭该服务,避免耗费资源。

    二、源码分析

    还是结合源码来分析这两个类的工作原理,首先看下HandlerThread的源码实现,源码不是很多,我就全部放进来了:

    public class HandlerThread extends Thread {//继承自Thread类
        int mPriority;
        int mTid = -1;
        Looper mLooper;//内部维护一个Looper
    
        public HandlerThread(String name) {
            super(name);
            mPriority = Process.THREAD_PRIORITY_DEFAULT;//线程优先级用的默认优先级
        }
        
        public HandlerThread(String name, int priority) {
            super(name);
            mPriority = priority;
        }
        
     
        protected void onLooperPrepared() { //用户可以重写该方法,在Looper.loop()之前做一些准备工作
        }
    
        @Override
        public void run() {//线程体执行的内容
            mTid = Process.myTid();
            Looper.prepare();
            synchronized (this) {
                mLooper = Looper.myLooper();//获得一个Looper
                notifyAll();
            }
            Process.setThreadPriority(mPriority);
            onLooperPrepared();//hook onLooperPrepared
            Looper.loop();//启动消息循环
            mTid = -1;
        }
        
     
        public Looper getLooper() {
            if (!isAlive()) {
                return null;
            }
            synchronized (this) {
                while (isAlive() && mLooper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
            return mLooper;
        }
    
       
        public boolean quit() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quit();
                return true;
            }
            return false;
        }
    
     
        public boolean quitSafely() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quitSafely();
                return true;
            }
            return false;
        }
    
        public int getThreadId() {
            return mTid;
        }
    }
    

    从上述代码中可以看出:
    1.HandlerThread确实是一个线程;
    2.HandlerThread中维护了一个Looper对象,在线程执行体内启动了Looper.loop()。

    下面看下IntentService的源码,代码量也不是很多:

    public abstract class IntentService extends Service {
        private volatile Looper mServiceLooper;
        private volatile ServiceHandler mServiceHandler;//内部使用了一个Handler
        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);//收到消息后,回调onHandleIntent()方法 注意该方法的调用是在非主线程中调用的
                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 + "]");//在Service
     OnCreate中,使用HandlerThread 启动一个带Looper的线程
            thread.start();
    
            mServiceLooper = thread.getLooper();//获取到Looper
            mServiceHandler = new ServiceHandler(mServiceLooper);//生成一个Handler ,前边讲过,Handler的生成需要Looper。
        }
    
        @Override
        public void onStart(@Nullable Intent intent, int startId) {
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);//在onStart()方法中发送一个消息
        }
    
      
        @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);//重写方法 讲耗时的内容在该方法体实现
    }
    

    三、总结

    通过上边两个类的源码分析,我们可以总结出:
    1.HandlerThread是一个线程,在线程启动的时候启动消息队列;
    2.IntentService 是一个继承自Service的类,他通过在Service服务中开启HandlerThread的消息队列;
    3.使用HandlerThread的Looper来生成一个Handler对象,在onStart()方法中发送消息,然后执行onHandleIntent()方法;
    4.onHandleIntent在子线程中执行,我们可以将耗时任务放在这个方法中实现。

    至于Handler机制不在本文讨论,但本文的理解需要基于Handler工作机制。有机会再给大家分析Handler的工作机制。

    感谢你的耐心阅读,如有错误,欢迎指正。如果本文对你有帮助,记得点赞。欢迎关注我的微信公众号。


    qrcode_for_gh_84a02a29fedd_430.jpg

    相关文章

      网友评论

          本文标题:唠唠 HandlerThread 和 IntentService

          本文链接:https://www.haomeiwen.com/subject/pnsibxtx.html