赞
踩
这个Thread实例有可能是UI主线程,也有可能是自定义线程 :)
Android开发中Handler处理Message分两种情况:
1.Handler在应用主线程中处理Message
2.Handler在自建的线程中处理Message
对于第1种情况先按下不表,等分析完第2种情况后再回过头来看第1种情况会容易很多。
对于第2种情况,开发情景一般如下面例子的代码,先上全部代码:
- // 自定义类ExampleThread继承自Thread,内部Handler成员internalHandler
- class ExampleThread extends Thread {
-
- private static final String TAG = "ExampleThread";
- private static final int MSG_WORK = 1;
- private static final int MSG_PLAY_GAMES = 2;
- private Handler internalHandler;
-
- @Override
- public void run() {
- Looper.prepare();
- synchronized (ExampleThread.this) {
- internalHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_WORK:
- Log.d(TAG, "I'm working");
- break;
- case MSG_PLAY_GAMES:
- Log.d(TAG, "I'm playing games");
- break;
- default:
- break;
- }
- }
- };
- ExampleThread.this.notifyAll();
- }
- Looper.loop();
- }
-
- public void goWork() {
- while (internalHandler == null) {
- try {
- wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- internalHandler.sendEmptyMessage(MSG_WORK);
- }
-
- public void goPlayGames() {
- while (internalHandler == null) {
- try {
- wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- Message msg = Message.obtain(internalHandler, MSG_PLAY_GAMES);
- msg.sendToTarget();
- }
- }
-
- // 测试代码,goWork和goPlayGames方法的实现都是通过internalHandler发送Message,internalHandler是在exampleThread线程内部处理Message
- public void test() {
- ExampleThread exampleThread = new ExampleThread();
- exampleThread.start();
- exampleThread.goWork();
- exampleThread.goPlayGames();
- }
那我们只能一步步来分析了。
先看Looper.prepare();做了些是什么,上Looper的关键源码:
- package android.os;
- public final class Looper {
- private static final String TAG = "Looper";
- /*ThreadLocal类用来提供线程内部的局部变量。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量*/
- static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
- /*当所在线程为UI主线程时sMainLooper才会被使用到*/
- private static Looper sMainLooper;
- /*Looper持有的消息队列*/
- final MessageQueue mQueue;
- /*Looper所在线程的实例*/
- final Thread mThread;
-
- /*自定义线程调用此方法来prepare*/
- public static void prepare() {
- prepare(true);
- }
-
- private static void prepare(boolean quitAllowed) {
- /*如果sThreadLocal.get()不为null,则表示Looper已经prepare过了,不能重复prepare*/
- if (sThreadLocal.get() != null) {
- throw new RuntimeException("Only one Looper may be created per thread");
- }
- /*调用Looper构造器创建一个Looper实例,并set进sThreadLocal。由于ThreadLocal的特性,在同一线程(当前线程)中我们通过sThreadLocal.get()得到的都是同一个Looper实例;而在不同线程中我们通过sThreadLocal.get()得到的又是不同的Looper实例。*/
- sThreadLocal.set(new Looper(quitAllowed));
- }
-
- private Looper(boolean quitAllowed) {
- /*创建一个消息队列*/
- mQueue = new MessageQueue(quitAllowed);
- /*获得当前线程的实例*/
- mThread = Thread.currentThread();
- }
-
- /*UI主线程调用此方法来prepare*/
- public static void prepareMainLooper() {
- /*也是通过调用prepare来创建Looper实例*/
- prepare(false);
- synchronized (Looper.class) {
- if (sMainLooper != null) {
- throw new IllegalStateException("The main Looper has already been prepared.");
- }
- /*跟自定义线程不同的是把创建的Loooper实例赋给了sMainLooper引用*/
- sMainLooper = myLooper();
- }
- }
-
- /*其他进程要跟UI主线程IPC的话可以通过此方法获得主线程的Looper,然后向主线程发送事件,比如按键事件等*/
- public static Looper getMainLooper() {
- synchronized (Looper.class) {
- return sMainLooper;
- }
- }
-
- /*Looper开始工作*/
- public static void loop() {
- final Looper me = myLooper();
- if (me == null) {
- throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
- }
- /*当前Looper持有的消息队列*/
- final MessageQueue queue = me.mQueue;
-
- for (;;) {
- /*从消息队列中取出下一条Message,可能会阻塞*/
- Message msg = queue.next();
- if (msg == null) {
- /*表示消息队列正在quitting*/
- return;
- }
- /*取出来的Message交给target(即Handler,为什么target是Handler等后面Message源码部分再说)去调度处理*/
- msg.target.dispatchMessage(msg);
- /*Message处理完后释放资源*/
- msg.recycleUnchecked();
- }
- }
-
- /*prepare时把创建的Looper实例set进了sThreadLocal,所以在同一线程中myLooper方法得到的肯定是同一个Looper实例,所以一个Thread实例只有一个Looper实例*/
- public static @Nullable Looper myLooper() {
- return sThreadLocal.get();
- }
-
- /*在Looper的构造器中创建了MessageQueue,由myLooper()性质决定了同一线程中myQueue方法得到的肯定也是同一个MessageQueue实例*/
- public static @NonNull MessageQueue myQueue() {
- return myLooper().mQueue;
- }
-
- /*判断是否在当前线程中。比如在线程A的代码中aLooper = myLooper()来获得线程A的Looper实例aLooper,然后可能在任何代码地方通过aLooper.isCurrentThread()来判断所在代码是否运行在线程A中*/
- public boolean isCurrentThread() {
- return Thread.currentThread() == mThread;
- }
-
- /*退出消息队列,当前消息队列中未被处理的消息将被丢弃。一旦调用quit后再向消息队列中推送消息就会失败,例如Handler.sendMessage(Message)会返回false*/
- public void quit() {
- mQueue.quit(false);
- }
-
- /*安全退出消息队列,当前消息队列中的消息都会被处理完。同样,一旦调用quit后再向消息队列中推送消息就会失败,例如Handler.sendMessage(Message)会返回false*/
- public void quitSafely() {
- mQueue.quit(true);
- }
-
- /*获得Looper实例中的当前线程实例*/
- public @NonNull Thread getThread() {
- return mThread;
- }
-
- /*获得Looper实例持有的消息队列,此方法为非静态方法,myQueue()为静态方法*/
- public @NonNull MessageQueue getQueue() {
- return mQueue;
- }
- }
- package android.os;
- public class Handler {
-
- private static final String TAG = "Handler";
- /*当前线程中的消息队列*/
- final MessageQueue mQueue;
- /*当前队列中的Looper*/
- final Looper mLooper;
- /*Handler的内部回调,Handler构造器中可以传入Callback,如果传入了此Callback,则Message将交给此Callback的handleMessage去处理,而不是交给Handler的handleMessage去处理*/
- final Callback mCallback;
- final boolean mAsynchronous;
-
- public interface Callback {
- public boolean handleMessage(Message msg);
- }
-
- /*Handler有很多构造器,无参构造器的话传入的Callback为null*/
- public Handler() {
- this(null, false);
- }
-
- public Handler(Callback callback) {
- this(callback, false);
- }
-
- public Handler(boolean async) {
- this(null, async);
- }
-
- public Handler(Callback callback, boolean async) {
- /*获得当前线程中的Looper实例*/
- mLooper = Looper.myLooper();
- /*如果Looper实例为空,说明当前线程还没有调用Looper.prepare*/
- if (mLooper == null) {
- throw new RuntimeException(
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- /*获得当前线程中的消息队列*/
- mQueue = mLooper.mQueue;
- /*保存构造器传入的callback*/
- mCallback = callback;
- mAsynchronous = async;
- }
-
- /*向消息队列中推送一个Runnable,通过getPostMessage把Runnable封装成Message,调用sendMessageDelayed继续处理*/
- public final boolean post(Runnable r) {
- return sendMessageDelayed(getPostMessage(r), 0);
- }
-
- /*Runnable封装成Message*/
- private static Message getPostMessage(Runnable r) {
- Message m = Message.obtain();
- /*Runnable实例成了Message的callback成员变量*/
- m.callback = r;
- return m;
- }
-
- /*向消息队列中推送一个Message,调用sendMessageDelayed继续处理*/
- public final boolean sendMessage(Message msg) {
- return sendMessageDelayed(msg, 0);
- }
-
- /*sendMessageDelayed调用sendMessageAtTime继续处理*/
- public final boolean sendMessageDelayed(Message msg, long delayMillis) {
- if (delayMillis < 0) {
- delayMillis = 0;
- }
- return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
-
- /*无论是向消息队列中推送Runnable还是Message,最后都走到了这个方法中*/
- public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- MessageQueue queue = mQueue;
- /*如果当前线程的消息队列为null,说明出了问题,推送会失败*/
- if (queue == null) {
- RuntimeException e = new RuntimeException(
- this + " sendMessageAtTime() called with no mQueue");
- Log.w("Looper", e.getMessage(), e);
- return false;
- }
- /*把Message推送到消息队列中*/
- return enqueueMessage(queue, msg, uptimeMillis);
- }
-
- private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
- /*把Message的target成员设置成了当前Handler。所以在Looper.loop()中的msg.target.dispatchMessage(msg);即调用了Handler的dispatchMessage*/
- msg.target = this;
- if (mAsynchronous) {
- msg.setAsynchronous(true);
- }
- /*把Message压入队列*/
- return queue.enqueueMessage(msg, uptimeMillis);
- }
-
- /*Looper.loop()中获得到待处理的Message后会调度到此处继续处理*/
- public void dispatchMessage(Message msg) {
- /*msg.callback在getPostMessage方法中赋值,msg.callback即为Runnable,如果Message成员中Runnable不为空则直接处理Runnable*/
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- /*mCallback在Handler构造器中赋值,如果有Callback就交给Callback来处理Message*/
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- /*最低优先级是由Handler的handleMessage来处理Message,子类一般会重载Handler的handleMessage*/
- handleMessage(msg);
- }
- }
-
- /*Message成员中Runnable的处理*/
- private static void handleCallback(Message message) {
- message.callback.run();
- }
-
- /*子类重载此方法来处理Message*/
- public void handleMessage(Message msg) {
- }
- }
Handler在自定义线程中处理Message的情况分析完了,接着分析看看在UI主线程中Handler处理Message的机制是怎么搭建好的呢?
应用程序启动时会创建主线程,即ActivityThread,四大组件无论哪一个启动都是创建的ActivityThread。
上ActivityThread的main方法的源码:
- public static void main(String[] args) {
- Looper.prepareMainLooper();
- ActivityThread thread = new ActivityThread();
- if (sMainThreadHandler == null) {
- sMainThreadHandler = thread.getHandler();
- }
- Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited");
- }
- final Handler getHandler() {
- return mH;
- }
-
- final H mH = new H();
- private class H extends Handler {}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。