文章目录
一、Handler 常用用法
二、HandlerThread 简介
三、HandlerThread 源码
一、Handler 常用用法
主线程 Handler 主要作用 : Looper 和 Message 都在 主线程 , Handler 也在 主线程 初始化 , 在子线程中调用该 Handler , 通知主线程进行一些操作 , 一般是更新 UI ;
子线程 Handler 主要作用 : Looper 和 Message 都在 子线程 , Handler 也在 子线程 初始化 , 在主线程中调用该 Handler , 通知子线程进行一些操作 , 一般是网络操作 , 计算 , 或其它耗时任务 ;
二、HandlerThread 简介
HandlerThread 就是使用了 Handler 机制的线程 , 其本质是一个 线程 Thread ; 属于上述介绍的 子线程 Handler 机制 ;
在运行 HandlerThread 线程的 run 方法时 ,
在 run 方法开始处 , 会调用 Looper.prepare() 方法 , 初始化该线程的 Looper ,
在 run 方法结束处 , 会调用 Looper.loop() 方法 , 开启无限循环 , 从 Looper 中的 MessageQueue 中循环获取消息 , 并转发给 取出的 Message 消息对应的 Handler 进行相关任务处理 ;
HandlerThread 线程的 run() 方法如下 :
public class HandlerThread extends Thread { @Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } }
三、HandlerThread 源码
/** * 含有 Looper 的线程. * Looper 用于创建 Handler. * <p> * 该类是一个线程类, 必须调用 start 方法开启线程. */ public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } /** * 创建 HandlerThread. * @param name * @param priority 线程运行优先级 */ public HandlerThread(String name, int priority) { super(name); mPriority = priority; } /** * Looper 无限循环之前执行的操作 */ protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); // Looper 初始化 Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); // 无限循环获取消息并执行 Looper.loop(); mTid = -1; } /** * 返回与该线程关联的 Looper . * 如果线程没有启动 , 或者线程不处于活动状态 , 返回空. * 如果线程已经启动 , 该方法会阻塞 , 直到 Looper 被初始化完毕后 , 返回 Looper. * @return The looper. */ public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } /** * @return 返回一个与该线程关联的共享 Handler * @hide */ @NonNull public Handler getThreadHandler() { if (mHandler == null) { mHandler = new Handler(getLooper()); } return mHandler; } /** * 退出 Looper 循环. * <p> * Causes the handler thread's looper to terminate without processing any * more messages in the message queue. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p class="note"> * Using this method may be unsafe because some messages may not be delivered * before the looper terminates. Consider using {@link #quitSafely} instead to ensure * that all pending work is completed in an orderly manner. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. * * @see #quitSafely */ public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false; } /** * 安全退出线程 loop. * <p> * Causes the handler thread's looper to terminate as soon as all remaining messages * in the message queue that are already due to be delivered have been handled. * Pending delayed messages with due times in the future will not be delivered. * </p><p> * Any attempt to post messages to the queue after the looper is asked to quit will fail. * For example, the {@link Handler#sendMessage(Message)} method will return false. * </p><p> * If the thread has not been started or has finished (that is if * {@link #getLooper} returns null), then false is returned. * Otherwise the looper is asked to quit and true is returned. * </p> * * @return True if the looper looper has been asked to quit or false if the * thread had not yet started running. */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * 返回线程 ID */ public int getThreadId() { return mTid; } }