为什么需要Handler
Handler的主要作用是将一个任务切换到某个指定的指定的线程中执行。而Handler常常可以用于在子线程更新UI。
系统为什么不允许在子线程更新UI呢?这是因为Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态。那么为什么系统不对UI控件的访问加上锁机制呢?缺点有两个:首先加上锁机制会让UI访问的逻辑变得复杂;其次,锁机制会降低UI的访问效率,因为锁机制会阻塞某些线程的执行。鉴于这两个缺点,最简单且高效的方法就是采用单线程模型来处理UI操作,对于开发者来说也不是很麻烦,只是需要通过Handler切换一下UI访问的执行线程即可。
概述
Handler运行需要底层的MessageQueue和Looper支撑。其中MessageQueue采用的是单链表的结构,Looper可以叫做消息循环。由于MessageQueue只是一个消息存储单元,不能去处理消息,而Looper就是专门来处理消息的,Looper会以无限循环的形式去查找是否有新消息,如果有的话,就处理,否则就一直等待着。
当Looper发现有新消息到来时,就会处理这个消息,最终消息中的Runnable或者Handler的handleMessage方法就会被调用。注意Looper是运行在创建Handler所在的线程中的,这样一来Handler中的业务逻辑就被切换到创建Handler所在的线程中去执行了。
我们知道,Handler创建的时候会采用 当前线程 的Looper来构造消息循环系统,需要注意的是,线程默认是没有Looper的,如果需要使用Handler就必须为线程创建Looper,因为默认的UI主线程,也就是ActivityThread,ActivityThread被创建的时候就会初始化Looper,这也是在主线程中默认可以使用Handler的原因。
Message
定义:是线程间通讯的数据单元,包含着描述信息及任意数据对象,发送到 Handler。
在实际使用中,我们在工作线程中通过 Handler.sendMessage(Message),将携带数据的 Message 信息发送给 Handler,然后再由 Handler 处理,根据不同的信息,通知主线程作出相对应的 UI 工作。
MessageQueue 消息队列
定义:用来存储 Message 的数据队列。
主要包含两个操作:插入和读取。读取操作本身会伴随着删除操作。插入对应的方法为enqueueMessage,读取对应的方法为next。next方法是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞在这里。当有新消息到来时,next会返回这条消息并将其从单链表中移除。
Looper 消息循环器
定义:用于为线程执行消息循环的一个类。是 MessageQueue 与 Handler 之间的通讯媒介。
会不停地从MessageQueue中查看是否有新消息,如果有新消息就立即处理,否则就一直阻塞在那里。
在子线程中,如果手动为其创建了Looper,那么在所有的事情完成以后应该调用quit方法来终止消息循环,否则这个子线程就会一直处于等待状态。而**如果退出Looper以后,这个线程就会立刻终止 **。因此建议在不需要的时候终止Looper
关系
存储在 MessageQueue 中的 Message 被 Looper 循环分发到指定的 Handler 中进行处理
一个 Thread 可以有多个 Handler。
但一个 Thread 只能有一个 Looper,即在该线程调用Looper.prepare()创建的Looper
一个 Handler 只能关联一个 Looper 对象,即创建Handler线程的Looper
反之,一个 Looper 可以被多个 Handler 所关联
一个Looper创建一个MessageQueue
Handler的构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 @UnsupportedAppUsage final Looper mLooper;final MessageQueue mQueue;@UnsupportedAppUsage final Callback mCallback;final boolean mAsynchronous;public Handler () { this (null , false ); } public Handler (@Nullable Callback callback) { this (callback, false ); } public Handler (@NonNull Looper looper) { this (looper, null , false ); } public Handler (@NonNull Looper looper, @Nullable Callback callback) { this (looper, callback, false ); } @UnsupportedAppUsage public Handler (boolean async) { this (null , async); } public Handler (@Nullable Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0 ) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null ) { throw new RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()" ); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
Handler的使用
1.新建Handler子类(内部类) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; static class Mhandler extends Handler { @Override public void handleMessage (Message msg) { switch (msg.what) { case 1 : mTextView.setText("执行了线程1的UI操作" ); break ; case 2 : mTextView.setText("执行了线程2的UI操作" ); break ; } } } @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); mHandler = new Mhandler(); new Thread() { @Override public void run () { try { Thread.sleep(3000 ); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = Message.obtain(); msg.what = 1 ; msg.obj = "A" ; mHandler.sendMessage(msg); } }.start(); new Thread() { @Override public void run () { try { Thread.sleep(6000 ); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = Message.obtain(); msg.what = 2 ; msg.obj = "B" ; mHandler.sendMessage(msg); } }.start(); } }
2.匿名内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); mHandler = new Handler(){ @Override public void handleMessage (Message msg) { switch (msg.what) { case 1 : mTextView.setText("执行了线程1的UI操作" ); break ; } } }; new Thread() { @Override public void run () { try { Thread.sleep(3000 ); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = Message.obtain(); msg.what = 1 ; msg.obj = "A" ; mHandler.sendMessage(msg); } }.start(); } }
3.Handler.post(Runnable) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class MainActivity extends AppCompatActivity { public TextView mTextView; public Handler mHandler; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.show); mHandler = new Handler(); new Thread() { @Override public void run () { try { Thread.sleep(3000 ); } catch (InterruptedException e) { e.printStackTrace(); } mHandler.post(new Runnable() { @Override public void run () { mTextView.setText("执行了线程1的UI操作" ); } }); } }.start(); } }
先看一下sendMessage的源码分析一下执行过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public final boolean sendMessage (@NonNull Message msg) { return sendMessageDelayed(msg, 0 ); } public final boolean sendMessageDelayed (@NonNull Message msg, long delayMillis) { if (delayMillis < 0 ) { delayMillis = 0 ; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } public boolean sendMessageAtTime (@NonNull Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null ) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue" ); Log.w("Looper" , e.getMessage(), e); return false ; } return enqueueMessage(queue, msg, uptimeMillis); } private boolean enqueueMessage (@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis) { msg.target = this ; msg.workSourceUid = ThreadLocalWorkSource.getUid(); if (mAsynchronous) { msg.setAsynchronous(true ); } return queue.enqueueMessage(msg, uptimeMillis); }
可以发现,Handler发送消息的过程仅仅是向消息队列插入了一条消息(调用MessageQueue的enqueueMessage方法)。MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理,最终交由Handler处理。即Handler的dispatchMessage方法被调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 public void dispatchMessage (@NonNull Message msg) { if (msg.callback != null ) { handleCallback(msg); } else { if (mCallback != null ) { if (mCallback.handleMessage(msg)) { return ; } } handleMessage(msg); } }
Handler处理消息的过程如下:
首先,检查Message的callback(msg.callback)是否为null,不为null就通过handleCallback来处理消息。这里的msg.callback即为Handler的post方法传进来的Runnable对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public final boolean post (@NonNull Runnable r) { return sendMessageDelayed(getPostMessage(r), 0 ); } private static Message getPostMessage (Runnable r) { Message m = Message.obtain(); m.callback = r; return m; } @UnsupportedAppUsage private static Message getPostMessage (Runnable r, Object token) { Message m = Message.obtain(); m.obj = token; m.callback = r; return m; } private static void handleCallback (Message message) { message.callback.run(); }
其次检查mCallback是否为null。不为null就调用mCallback的HandleMessage方法来处理消息。Callback是个接口,定义如下:
1 2 3 4 5 6 7 8 public interface Callback { boolean handleMessage (@NonNull Message msg) ; }
通过Callback可以通过Handler handler=new Handler(callback)来创建Handler对象。其作用在于可以用来创建Handler实例而不需要派生Handler的子类
最后调用Handler的handleMessage方法来处理消息。handleMessage方法是Handler子类需要实现的。
子线程创建Handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class CustomChildThread extends Thread { @Override public void run () { Looper.prepare(); Handler handler = new Handler() { public void handleMessage (Message msg) { } }; Looper.loop(); } }