关于Handler的原理,看了很多博客,个人认为以下三篇文章讲的不错,第一篇篇幅最短,虽然没有源码讲解,但结合流程图概括的很精炼;第二篇稍长,是CSDN博客专家——鸿洋写的,结合源码分析,简单易懂;最后一篇就更详细但也更冗长了:

Android应用程序消息处理机制
Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
Android 消息处理机制(Looper、Handler、MessageQueue,Message)

最后一篇中作者有条结论:

Handler 对象在哪个线程下构建(Handler的构造函数在哪个线程下调用),那么Handler 就会持有这个线程的Looper引用和这个线程的消息队列的引用。因为持有这个线程的消息队列的引用,意味着这个Handler对象可以在任意其他线程给该线程的消息队列添加消息,也意味着Handler的handleMessage 肯定也是在该线程执行的。

以上结论其实只概括了一部分,因为Handler的构造方法有很多种,以上结论只适用于不传Looper的构造方法,诸如:

public Handler()public Handler(Callback callback)

这些构造方法默认与当前线程的Looper绑定【通过mLooper = Looper.myLooper();】,所以说哪个线程创建了Handler对象,handleMessage就在哪个线程执行。
但是当使用参数中含有Looper的构造方法时,诸如:

public Handler(Looper looper)public Handler(Looper looper, Callback callback)

那么此时无论Handler对象是在哪个线程构建的,该Handler对象所持有的Looper和MessageQueue都是构造方法中传入的那个Looper,而这个Looper一般都是与其他线程绑定的(否则就没必要使用这个构造函数了),此时相当于在当前线程下构造了一个与指定线程绑定的Handler对象,可以通过该Handler对象向指定线程发送消息,当然该Handler对象的handlerMessage也是运行在指定线程上的。
所以,可以得出结论,handler对象所绑定的线程其实并不取决于该handler对象由哪个线程构建,而是取决于该handler对象所绑定的Looper属于哪个线程
以下的demo可以验证结论:
MyHandlerThread.java:

package com.example.weishj.mytester.handler;import android.os.Handler;import android.os.Message;import android.util.Log;/** * Created by weishj on 2017/6/21. */public abstract class MyHandlerThread implements Handler.Callback {protected final Handler handler;public MyHandlerThread() {Log.e("MyHandlerThread", "Create MyHandlerThread. tid=" + Thread.currentThread().getId());android.os.HandlerThread t2 = new android.os.HandlerThread("MyHandlerThread");t2.start();Log.e("MyHandlerThread", "start t2. t2.tid=" + t2.getId());this.handler = new Handler(t2.getLooper(), this); // handler持有的是t2的Looper和MessageQueue}public final boolean handleMessage(Message msg) {// 处理this.handler发过来的消息switch(msg.what) {case 1:Log.e("MyHandlerThread", "handled message. tid=" + Thread.currentThread().getId());break;default:break;}return false;}}

Sub.java:

package com.example.weishj.mytester.handler;import android.os.Message;import android.util.Log;/** * Created by weishj on 2017/6/21. */public class Sub extends MyHandlerThread {public Sub() {Log.e("Sub", "Create Sub. tid=" + Thread.currentThread().getId());}// 对外提供一个方法,用于发送消息public void sendMessage() {Message msg = new Message();msg.what = 1;msg.obj = "test data";super.handler.sendMessage(msg);}}

MainActivity.java:

package com.example.weishj.mytester;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import com.example.weishj.mytester.handler.Sub;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e("MainActivity", "MainActivity onCreate. tid=" + Thread.currentThread().getId());// 我在程序的某处, 如此调用Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {Sub sub = new Sub();sub.sendMessage();}});t1.start();Log.e("MainActivity", "Start t1. t1.tid=" + t1.getId());}}

demo运行后,最终输出为:
06-22 10:36:44.607 2305-2305/com.example.weishj.mytester E/MainActivity: MainActivity onCreate. tid=1
06-22 10:36:44.608 2305-2305/com.example.weishj.mytester E/MainActivity: Start t1. t1.tid=1673
06-22 10:36:44.609 2305-2381/com.example.weishj.mytester E/MyHandlerThread: Create MyHandlerThread. tid=1673
06-22 10:36:44.610 2305-2381/com.example.weishj.mytester E/MyHandlerThread: start t2. t2.tid=1674
06-22 10:36:44.610 2305-2381/com.example.weishj.mytester E/Sub: Create Sub. tid=1673
06-22 10:36:44.613 2305-2382/com.example.weishj.mytester E/MyHandlerThread: handled message. tid=1674
handler对象是MyHandlerThread的一个成员变量,而MyHandlerThread是在线程1673构建的,所以这个handler对象也是在1673构建的,然而最终handleMessage是在线程1674上执行的,也就是构建handler对象时传入的t2.getLooper()所对应的线程t2。

更多相关文章

  1. 【Android】注解框架(一)-- 基础知识Java 反射
  2. Parcalable接口使用(android传递结构体数据的方法)
  3. 第十章、Android的消息机制
  4. Android,谁动了我的内存(转)
  5. Android中解决图像解码导致的OOM问题
  6. Android键盘系统
  7. Android(安卓)AsyncTask理解及简单用法
  8. Android开发规范详解
  9. 【Android】进程与线程基本知识

随机推荐

  1. Android(安卓)7.1 设置不支持遥控操作?
  2. 安卓按钮有按下去的效果的实现方法
  3. Android中Media Framework浅析(二)——Medi
  4. Android之如何解决右上角不显示3个点的菜
  5. Android开发之EditText属性详解
  6. 【Android开发】完善搜索功能-添加最近查
  7. 【转】Android(安卓)OTA 升级之一:编译升
  8. 《你知道android的MessageQueue.IdleHand
  9. 我的Android进阶之旅------>经典的大牛博
  10. [Android]MPAndroidChart的实战使用讲解