唠唠 HandlerThread 和 IntentService

782 阅读3分钟

一、概述

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的工作机制。

感谢你的耐心阅读,如有错误,欢迎指正。如果本文对你有帮助,记得点赞.