message.target = this;//this即这个发送此Message的handler对象
"background-color:#2b2b2b">"color:#bababa">message.target.dispatchMessage(message); "color:#7f7f7f">//message.target即发送此Message的handler对象

- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">public "color:#cb7832">static "color:#cb7832">final "color:#cb7832">void "color:#81a2be">prepare"color:#b9b9b9">() {
- "color:#cb7832">if (sThreadLocal.get() != "color:#cb7832">null) "color:#cb7832">throw "color:#cb7832">new RuntimeException("color:#6a8759">"Only one Looper may be created per thread");
- sThreadLocal.set("color:#cb7832">new Looper("color:#cb7832">true));
- }
- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">private "color:#81a2be">Looper"color:#b9b9b9">("color:#cb7832">boolean quitAllowed) {
- mQueue = "color:#cb7832">new MessageQueue(quitAllowed);
- mRun = "color:#cb7832">true;
- mThread = Thread.currentThread();
- }
- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">public "color:#cb7832">static "color:#cb7832">void "color:#81a2be">loop"color:#b9b9b9">() {
- "color:#cb7832">final Looper me = myLooper();"color:#7f7f7f">//方法体为 return sThreadLocal.get(); 即此方法直接返回了sThreadLocal存储的Looper实例
- "color:#cb7832">if (me == "color:#cb7832">null) "color:#cb7832">throw "color:#cb7832">new RuntimeException("color:#6a8759">"No Looper; Looper.prepare() wasn't called on this thread.");"color:#7f7f7f">//如果me为null则抛出异常,也就是说looper方法必须在prepar()之后运行。
- "color:#cb7832">final MessageQueue queue = me.mQueue;"color:#7f7f7f">//拿到该looper实例中的消息队列
- Binder.clearCallingIdentity(); "color:#7f7f7f">// Make sure the identity of this thread is that of the local process, and keep track of what that identity token actually is.
- "color:#cb7832">final "color:#cb7832">long ident = Binder.clearCallingIdentity();
- "color:#7f7f7f">//无限循环
- "color:#cb7832">for (;;) {
- Message msg = queue.next(); "color:#7f7f7f">// might block,取出一条消息,如果没有消息则阻塞等待
- "color:#cb7832">if (msg == "color:#cb7832">null) "color:#cb7832">return;
- Printer logging = me.mLogging; "color:#7f7f7f">// This must be in a local variable, in case a UI event sets the logger
- "color:#cb7832">if (logging != "color:#cb7832">null) logging.println("color:#6a8759">">>>>> Dispatching to " + msg.target + "color:#6a8759">" " + msg.callback + "color:#6a8759">": " + msg.what);
- msg.target.dispatchMessage(msg);"color:#7f7f7f">//Msg的target其实就是handler对象
- "color:#cb7832">if (logging != "color:#cb7832">null) logging.println("color:#6a8759">"<<<<< Finished to " + msg.target + "color:#6a8759">" " + msg.callback);
- "color:#cb7832">final "color:#cb7832">long newIdent = Binder.clearCallingIdentity();"color:#7f7f7f">// Make sure that during the course of dispatching the identity of the thread wasn't corrupted.
- "color:#cb7832">if (ident != newIdent) {
- Log.wtf(TAG, "color:#6a8759">"Thread identity changed from 0x" + Long.toHexString(ident) + "color:#6a8759">" to 0x" + Long.toHexString(newIdent)
- + "color:#6a8759">" while dispatching to " + msg.target.getClass().getName() + "color:#6a8759">" " + msg.callback + "color:#6a8759">" what=" + msg.what);
- }
- msg.recycle();"color:#7f7f7f">//释放消息占据的资源
- }
- }
- "background-color:#2b2b2b"><span style="color:#bababa">public <span style="color:#be94bb"><span style="color:#81a2be">Handlerspan>()span> {<span style="color:#7f7f7f">//我们一般都是使用此无参的构造方法span>
- <span style="color:#e0c46c">thisspan>(<span style="color:#6896ba">nullspan>, <span style="color:#6896ba">falsespan>);
- }
- public <span style="color:#be94bb"><span style="color:#81a2be">Handlerspan>(<span style="color:#b9b9b9">Callback callback, boolean <span style="color:#cb7832">asyncspan>span>)span> {
- <span style="color:#cb7832">ifspan> (FIND_POTENTIAL_LEAKS) {
- final Class <span style="color:#cb7832">extendsspan> Handler> klass = getClass();
- <span style="color:#cb7832">ifspan> ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == <span style="color:#6896ba">0span>) {
- Log.w(TAG, <span style="color:#6a8759">"The following Handler class should be static or leaks might occur: "span> + klass.getCanonicalName());
- }
- }
- mLooper = Looper.myLooper();<span style="color:#7f7f7f">//获取当前线程保存的Looper实例span>
- <span style="color:#cb7832">ifspan> (mLooper == <span style="color:#6896ba">nullspan>) <span style="color:#cb7832">throwspan> <span style="color:#cb7832">newspan> RuntimeException(<span style="color:#6a8759">"Can't create handler inside thread that has not called Looper.prepare()"span>);<span style="color:#7f7f7f">//在初始化Handler之前必须先通过Looper.prepare()方法创建Looper的实例span>
- mQueue = mLooper.mQueue;<span style="color:#7f7f7f">//获取这个Looper实例中保存的MessageQueue(消息队列)span>
- mCallback = callback;
- mAsynchronous = <span style="color:#cb7832">asyncspan>;
- }span>
- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">public "color:#cb7832">final "color:#cb7832">boolean "color:#81a2be">sendMessage"color:#b9b9b9">(Message msg) {
- "color:#cb7832">return sendMessageDelayed(msg, "color:#6896ba">0);
- }
-
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">final "color:#cb7832">boolean "color:#81a2be">sendEmptyMessageDelayed"color:#b9b9b9">("color:#cb7832">int what, "color:#cb7832">long delayMillis) {
- Message msg = Message.obtain();
- msg.what = what;
- "color:#cb7832">return sendMessageDelayed(msg, delayMillis);
- }
-
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">final "color:#cb7832">boolean "color:#81a2be">sendMessageDelayed"color:#b9b9b9">(Message msg, "color:#cb7832">long delayMillis) {
- "color:#cb7832">if (delayMillis < "color:#6896ba">0) delayMillis = "color:#6896ba">0;
- "color:#cb7832">return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- }
-
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">boolean "color:#81a2be">sendMessageAtTime"color:#b9b9b9">(Message msg, "color:#cb7832">long uptimeMillis) {
- MessageQueue queue = mQueue;
- "color:#cb7832">if (queue == "color:#cb7832">null) {
- RuntimeException e = "color:#cb7832">new RuntimeException("color:#cb7832">this + "color:#6a8759">" sendMessageAtTime() called with no mQueue");
- Log.w("color:#6a8759">"Looper", e.getMessage(), e);
- "color:#cb7832">return "color:#cb7832">false;
- }
- "color:#cb7832">return enqueueMessage(queue, msg, uptimeMillis);
- }
- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">private "color:#cb7832">boolean "color:#81a2be">enqueueMessage"color:#b9b9b9">(MessageQueue queue, Message msg, "color:#cb7832">long uptimeMillis) {
- msg.target = "color:#cb7832">this;
- "color:#cb7832">if (mAsynchronous) msg.setAsynchronous("color:#cb7832">true);
- "color:#cb7832">return queue.enqueueMessage(msg, uptimeMillis);
- }
- "background-color:#2b2b2b">"color:#bababa">"color:#be94bb">"color:#cb7832">public "color:#cb7832">void "color:#81a2be">dispatchMessage"color:#b9b9b9">(Message msg) {
- "color:#cb7832">if (msg.callback != "color:#cb7832">null) handleCallback(msg);
- "color:#cb7832">else {
- "color:#cb7832">if (mCallback != "color:#cb7832">null) {
- "color:#cb7832">if (mCallback.handleMessage(msg)) "color:#cb7832">return;
- }
- handleMessage(msg);
- }
- }
可以看到,最后调用了handleMessage方法,可实际上这是一个空方法,为什么呢?因为消息的最终回调是由我们控制的,我们在创建handler的时候都是复写handleMessage方法,然后根据msg.what进行消息处理。
- "background-color:#2b2b2b">"color:#bababa">mHandler.post("color:#cb7832">new Runnable() {
- "color:#7f7f7f">@Override
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">void "color:#81a2be">run"color:#b9b9b9">() {
- mTxt.setText("color:#6a8759">"yoxi");"color:#7f7f7f">//在run方法中可以更新UI
- }
- });
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">final "color:#cb7832">boolean "color:#81a2be">post"color:#b9b9b9">(Runnable r) {
- "color:#cb7832">return sendMessageDelayed(getPostMessage(r), "color:#6896ba">0);
- }
- "color:#be94bb">"color:#cb7832">private "color:#cb7832">static Message "color:#81a2be">getPostMessage"color:#b9b9b9">(Runnable r) {
- Message m = Message.obtain();"color:#7f7f7f">//得到了一个Message对象
- m.callback = r;"color:#7f7f7f">//将我们创建的Runable对象作为callback属性,赋值给了此Message
- "color:#cb7832">return m;
- }
- "background-color:#2b2b2b">"color:#bababa">"color:#cb7832">public "color:#be94bb">"color:#cb7832">class "color:#81a2be">HandlerTestActivity "color:#cb7832">extends "color:#81a2be">ListActivity {
- "color:#cb7832">private TextView tv_info;
- "color:#cb7832">private Handler uiHandler;
- "color:#cb7832">private StaticThread thread;"color:#7f7f7f">//一个子线程
-
- "color:#cb7832">public "color:#cb7832">static "color:#cb7832">final "color:#cb7832">int MSG_WHAT_1 = "color:#6896ba">1;
- "color:#cb7832">public "color:#cb7832">static "color:#cb7832">final "color:#cb7832">int MSG_WHAT_2 = "color:#6896ba">2;
- "color:#cb7832">public "color:#cb7832">static "color:#cb7832">final "color:#cb7832">int MSG_WHAT_3 = "color:#6896ba">3;
-
- "color:#be94bb">"color:#cb7832">protected "color:#cb7832">void "color:#81a2be">onCreate"color:#b9b9b9">(Bundle savedInstanceState) {
- "color:#cb7832">super.onCreate(savedInstanceState);
- String[] array = {"color:#6a8759">"开启子线程,并在子线程中创建一个Handler", "color:#7f7f7f">//
- "color:#6a8759">"在主线程中,通过子线程的Handler[向子线程]发消息", "color:#7f7f7f">//
- "color:#6a8759">"演示Handler的post方法"};
- tv_info = "color:#cb7832">new TextView("color:#cb7832">this);
- tv_info.setText("color:#6a8759">"Handler、Looper、Message、MQ、Thread关系");
- getListView().addFooterView(tv_info);
- setListAdapter("color:#cb7832">new ArrayAdapter<>("color:#cb7832">this, android.R.layout.simple_list_item_1, "color:#cb7832">new ArrayList
(Arrays.asList(array)))); -
- uiHandler = "color:#cb7832">new StaticUiHandler("color:#cb7832">this); "color:#7f7f7f">//系统启动时已经为主线程初始化了Looper、MQ等,我们可以直接创建Handler
- thread = "color:#cb7832">new StaticThread("color:#cb7832">this);
- }
-
- "color:#7f7f7f">@Override
- "color:#be94bb">"color:#cb7832">protected "color:#cb7832">void "color:#81a2be">onDestroy"color:#b9b9b9">() {
- "color:#cb7832">super.onDestroy();
- "color:#cb7832">if (uiHandler != "color:#cb7832">null) uiHandler.removeCallbacksAndMessages("color:#cb7832">null);
- "color:#cb7832">if (thread != "color:#cb7832">null && thread.getAnsyHandler() != "color:#cb7832">null) thread.getAnsyHandler().removeCallbacksAndMessages("color:#cb7832">null);
- }
-
- "color:#7f7f7f">@Override
- "color:#be94bb">"color:#cb7832">protected "color:#cb7832">void "color:#81a2be">onListItemClick"color:#b9b9b9">(ListView l, View v, "color:#cb7832">int position, "color:#cb7832">long id) {
- "color:#cb7832">switch (position) {
- "color:#cb7832">case "color:#6896ba">0:"color:#7f7f7f">//开启子线程,并在子线程中创建一个Handler
- "color:#cb7832">if (thread != "color:#cb7832">null && !thread.isAlive()) thread.start();"color:#7f7f7f">//A thread is alive if it has been started and has not yet died.
- "color:#cb7832">break;
- "color:#cb7832">case "color:#6896ba">1:"color:#7f7f7f">//在主线程中,通过子线程的Handler[向子线程]发消息
- Message msg = Message.obtain("color:#cb7832">null, MSG_WHAT_1, "color:#6a8759">"消息内容"); "color:#7f7f7f">//第一个参数Handler的作用是指定msg.target
- "color:#7f7f7f">//这里设为null的原因是:后面调用sendMessage方法时重新指定了发送此消息的Handler为msg.target
- "color:#cb7832">if (thread != "color:#cb7832">null && thread.getAnsyHandler() != "color:#cb7832">null) thread.getAnsyHandler().sendMessage(msg);
- tv_info.append("color:#6a8759">"\n1、在UI线程中用子线程的Handler发消息,what=" + msg.what);
- "color:#cb7832">break;
- "color:#cb7832">case "color:#6896ba">2:
- "color:#7f7f7f">//其实这个Runnable并没有创建什么线程,而是发送了一条消息,当Handler收到此消息后回调run()方法
- uiHandler.post(() -> tv_info.append("color:#6a8759">"\n演示Handler的post方法"));
- "color:#cb7832">break;
- }
- }
- "color:#7f7f7f">//***********************************************静态内部类,防止内存泄漏*******************************************
-
- "color:#7f7f7f">/**
- * 主线程使用的Handler
- */
- "color:#cb7832">private "color:#cb7832">static "color:#be94bb">"color:#cb7832">class "color:#81a2be">StaticUiHandler "color:#cb7832">extends "color:#81a2be">Handler {
- "color:#cb7832">private SoftReference
mSoftReference; -
- "color:#be94bb">"color:#cb7832">public "color:#81a2be">StaticUiHandler"color:#b9b9b9">(HandlerTestActivity activity) {
- mSoftReference = "color:#cb7832">new SoftReference<>(activity);
- }
-
- "color:#7f7f7f">@Override
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">void "color:#81a2be">handleMessage"color:#b9b9b9">(Message msg) {
- HandlerTestActivity activity = mSoftReference.get();
- "color:#cb7832">if (activity != "color:#cb7832">null && activity.thread != "color:#cb7832">null && activity.thread.getAnsyHandler() != "color:#cb7832">null) {
- activity.tv_info.append("color:#6a8759">"\n4、UI线程的Handler收到消息,what=" + msg.what);
- Message msg3 = Message.obtain("color:#cb7832">null, MSG_WHAT_3, msg.obj);
- activity.thread.getAnsyHandler().sendMessageAtTime(msg3, SystemClock.uptimeMillis() + "color:#6896ba">2000);
- activity.tv_info.append("color:#6a8759">"\n5、在UI线程中用子线程的Handler发消息,what=" + msg3.what);
- }
- }
- }
-
- "color:#7f7f7f">/**
- * 异步线程(子线程)使用的Handler
- */
- "color:#cb7832">private "color:#cb7832">static "color:#be94bb">"color:#cb7832">class "color:#81a2be">StaticAnsyHandler "color:#cb7832">extends "color:#81a2be">Handler {
- "color:#cb7832">private SoftReference
mSoftReference; -
- "color:#be94bb">"color:#cb7832">public "color:#81a2be">StaticAnsyHandler"color:#b9b9b9">(HandlerTestActivity activity) {
- mSoftReference = "color:#cb7832">new SoftReference<>(activity);
- }
-
- "color:#7f7f7f">@Override
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">void "color:#81a2be">handleMessage"color:#b9b9b9">(Message msg) {
- HandlerTestActivity activity = mSoftReference.get();
-
- "color:#cb7832">if (activity != "color:#cb7832">null) {
- "color:#cb7832">final Message tempMsg = Message.obtain(msg);"color:#7f7f7f">//把收到的消息保存起来
- "color:#7f7f7f">//注意,一定要注意!根据消息池机制,当此消息不再在【此子线程】中使用时,此msg会立即被重置(引用虽在,内容为空)
- "color:#7f7f7f">//所以,如果想把此消息转发到其他线程,或者想在其他线程中引用此消息,一定要手动把消息保存起来!
-
- activity.runOnUiThread(() -> {"color:#7f7f7f">//在子线程中创建Handler的目的是为了和其他线程通讯,绝对不是(也不能)更新UI
- activity.tv_info.append("color:#6a8759">"\n2、子线程的Handler收到消息,what=" + tempMsg.what);
-
- "color:#cb7832">if (activity.uiHandler != "color:#cb7832">null && tempMsg.what == MSG_WHAT_1) {
- Message msg2 = Message.obtain("color:#cb7832">null, MSG_WHAT_2, tempMsg.obj);
- activity.uiHandler.sendMessageDelayed(msg2, "color:#6896ba">2000);
- "color:#7f7f7f">//注意,不能直接把一条还在使用的消息转发出去,否则IllegalStateException: This message is already in use
- activity.tv_info.append("color:#6a8759">"\n3、在子线程中用UI线程的Handler发消息,what=" + msg2.what);
- }
- });
- }
- }
- }
-
- "color:#7f7f7f">/**
- * 一个线程,用于执行耗时的操作
- */
- "color:#cb7832">private "color:#cb7832">static "color:#be94bb">"color:#cb7832">class "color:#81a2be">StaticThread "color:#cb7832">extends "color:#81a2be">Thread {
- "color:#cb7832">private SoftReference
mSoftReference; -
- "color:#be94bb">"color:#cb7832">public "color:#81a2be">StaticThread"color:#b9b9b9">(HandlerTestActivity activity) {
- mSoftReference = "color:#cb7832">new SoftReference<>(activity);
- }
-
- "color:#cb7832">private Handler ansyHandler;
-
- "color:#be94bb">"color:#cb7832">public Handler "color:#81a2be">getAnsyHandler"color:#b9b9b9">() {
- "color:#cb7832">return ansyHandler;
- }
-
- "color:#be94bb">"color:#cb7832">public "color:#cb7832">void "color:#81a2be">run"color:#b9b9b9">() {
- HandlerTestActivity activity = mSoftReference.get();
- "color:#cb7832">if (activity != "color:#cb7832">null) {
- Looper.prepare(); "color:#7f7f7f">//在创建Handler【前】必须调用此方法初始化Looper,否则直接报否则报RuntimeException崩溃
- "color:#7f7f7f">//里面做的事情:①为当前线程创建唯一的Looper对象 ②在它的构造方法中会创建一个的MessageQueue对象
- "color:#7f7f7f">//此方法只能被调用一次,这保证了在一个线程中只有一个Looper实例以及只有一个与其关联的MessageQueue实例
- ansyHandler = "color:#cb7832">new StaticAnsyHandler(activity); "color:#7f7f7f">//任何线程都可通过此Handler发送信息!
- Looper.loop(); "color:#7f7f7f">//若要能够接收到消息,创建Handler后,必须调用loop方法。当然此方法必须是在prepar之后执行
- "color:#7f7f7f">//里面做的事情:启动一个死循环,不断从MQ中取消息,没有则阻塞等待,有则将消息传给指定的Handler去处理
- activity.runOnUiThread(() -> Toast.makeText(activity, "color:#6a8759">"会一直阻塞在这里", Toast.LENGTH_SHORT).show());
- }
- }
- }
- }