Android 消息机制之初识Handler [ 六 ]

Android 消息机制深入源码分析 [ 一 ]
Android 消息机制之 ThreadLocal 深入源码分析 [ 二 ]
Android 消息机制之 Looper 深入源码分析 [ 三 ]
Android 消息机制之 Message 与消息对象池的深入源码分析 [ 四 ]
Android 消息机制之 MessageQueue 深入源码分析 [ 五 ]
Android 消息机制之初识Handler [ 六 ]
Android 消息机制之 Handler 发送消息的深入源码分析 [ 七 ]
Android 消息机制之 MessageQueue.next() 消息取出的深入源码分析 [ 八 ]
Android 消息机制之消息的其他处理深入源码分析 [ 九 ]
Android 消息机制总结 [ 十 ]

前几章分解学习了 ThreadLocal, Looper, Message, MessageQueue 等相关的知识, 本章节开始正式学习 Android 中消息机制的重中之重 Handler. 那么让我们正式开始学习吧.

1. 什么是 Handler

  • Handler 是一个可以通过关联一个消息队列来发送和处理消息, 发送或处理 Runnable 对象的一个处理程序.
  • 每个 Handler 都关联一个单个的线程和消息队列. 当我们创建一个新的 Handler 的时候, 它就绑定到一个线程上或者线程上的消息队列, 从那个时候起, 这个 Handler 就将为这个消息队列提供消息或者 Runnable 对象处理消息队列释放出来的消息或者 Runnable 对象.

2. Handler 有什么用

  • 安排消息和 Runnable 对象在未来执行.
  • 将用户的一个动作放在不同的线程上执行.

3. 构造函数

Handler 的构造函数一共有七个, 六个是有参, 一个无参的, 所有的构造函数都为 public

  • 1.public Handler()
  • 2.public Handler(Callback callback)
  • 3.public Handler(Looper looper)
  • 4.public Handler(Looper looper, Callback callback)
  • 5.public Handler(boolean async)
  • 6.public Handler(Callback callback, boolean async)
  • 7.public Handler(Looper looper, Callback callback, boolean async)

这七个构造函数, 又将分为两类. 分别为两个参数的 1. 2. 5. 6 和 三个参数的 3. 4. 7. 接下来将对这个构造函数逐个分析学习.

1. public Handler()

public Handler() {
    this(null, false);
}
  • 解析:

内部调用的构造 6. 只不过第一个传入的的为 null, 第二个传入的为 false.

2. public Handler(Callback callback)

public Handler(Callback callback) {
    this(callback, false);
}
  • 解析:

内部调用的也是构造 6.第一个传入参数为callback 回调, 第二个依然为false, 回调 Callback会放在后面分析. 目前暂时先知道是一个回调就行了.

5. public Handler(boolean async)

public Handler(boolean async) {
    this(null, async);
}
  • 解析:

内部调用的也是构造 ⑥,第一个传入null,第二个参数为boolean类型的async


 
以上是一个无参和两个有参的, 1. 2. 5. 但是他们归根结底调用的都是构造函数 6. 所以现在一起看下构造函数 6.
 
6. public Handler(Callback callback, boolean async)

public Handler(Callback callback, boolean async) {
    if (FIND_POTENTIAL_LEAKS) {
        final Class klass = getClass();
        //如果是匿名类, 内部类, 局部类,且没有声明 static,则存在内存泄露风险,所以打印日志进行提醒
        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());
        }
    }
    //获得当前线程的 Looper
    mLooper = Looper.myLooper();
    //如果当前线程没有 Looper,则说明没有还没有调用 Looper.loop,抛异常
    if (mLooper == null) {
        throw new RuntimeException("Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()");
    }
    //把 Looper 的 Queue 赋值给 Handler 的 mQueue
    mQueue = mLooper.mQueue;
    //赋值给 callback
    mCallback = callback;
    //赋值  mAsynchronous
    mAsynchronous = async;
}
  • 解析:

使用当前线程的 Looper, 使用传入的回调, 并设置这个 Handler 是否是异步的.
除非在创建 Handler 的时候指定为异步的, 否则默认的 Handler 默认都是同步的.
异步消息相对于同步消息而言, 表示消息不会受到终端或者事件的影响其全局顺序, 异步消息是不会受到MessageQueue.enqueueSyncBarrier(long) 的同步障栅影响

Handler 默认采用的是当前线程 ThreadLocal 中的 Looper 对象, 只要执行了 Looper.prepare() 方法, 就可以获取有效的 Looper 对象. 同时在 消息机制的第三篇 Looper 篇 的时候也说了 Looper 的构造函数关联了 MessageQueueThread.
所以在同一个线程里面(已经调用了 Looper.prepare()), Handler中的 MessageQueueLooper中的 MessageQueue 指向的是同一个消息队列.

 
下面是三个参数的构造函数.
3. public Handler(Looper looper)

public Handler(Looper looper) {
  this(looper, null, false);
}
  • 解析

内部调用了构造 7. 传入参数不同.

4. public Handler(Looper looper, Callback callback)

public Handler(Looper looper, Callback callback) {
    this(looper, callback, false);
}

不难发现, 上面两个默认调用的都是三个参数的构造函数, 都是非异步的.

7. public Handler(Looper looper, Callback callback, boolean async)

public Handler(Looper looper, Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}
  • 解析:

不使用默认的 Looper, 而使用由第一个参数传入的 Looper 对象.


 
综合 7 个构造函数, 可以发现其实构造函数的本质都是给下面四个本地变量赋值

  • mLooper
  • mQueue
  • mCallback
  • mAsynchronous

构造函数总结

  • 如果 Handler 的构造中没有给 Looper, 则使用默认的 Looper, 也就是在当前线程 ThreadLocal 中关联的 Looper.
    通过 ThreadLocal.Looper.mQueue 来给 Handler.mQueue 赋值.
    实现 Handler, Looper, MessageQueue 三者的绑定.
  • 通过构造函数来设置 Callback 的回调接口, 不设置则为 null.
  • 通过 mAsynchronous 来控制是同步还是异步, 而 mAsynchronous的默认值为 false. mAsynchronous 可以通过构造函数来设置.

 
最后来说一下回调接口, 也就是 Handler.Callback 接口

public interface Callback {
    public boolean handleMessage(Message msg);
}
  • 官方翻译:

通过设置这个接口去处理消息,就不需要再定义一个Handler的子类. 在调用 handler 构造函数的时候, 可直接使用这个接口. 返回值为 true 表示不继续向下分发, 返回 false 还会向下分发, 会调用 Handler.handleMessage() 方法. 在下一章 Handler 消息分发中会分析到.
(注意: 这个 handleMessage 可不是我们经常使用的那个. 这个是 callback 的 handleMessage.
我们经常使用的那个 handleMessageHandler 自带的一个方法. 也叫 handleMessage)

  • 理解

其实 Callback 可以和 Handelr.handleMessage 一起使用, 我尝试了一下, 可以产生类似过滤器的效果. 首先创建一个类继承自 Handler, 重写 void handleMessage 方法. 处理一些通用的消息. 然后在使用的 Activity 中, 创建 Handler 的时候, 使用我们自己定义的 Handelr, 其中参数传入 new Handler.Callback(), 并实现 boolean handleMessage . 在其中做一些处理. 示例如下.

class myHandler extends Handler{
    public myHandler(@Nullable Callback callback) {
        super(callback);
    }
    @Override
    public void handleMessage(@NonNull Message msg) {
        Log.e("myHandler","___what=" + msg.what);
        super.handleMessage(msg);
    }
}

public class MainActivity extends AppCompatActivity {

    Button button1,button2;
    private static  myHandler handler = new myHandler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            if(msg.what == 100){
                Log.e("myHandler","___Callback=" + msg.what);
                return true;
            }
            return  false;
        }
    });


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = Message.obtain();
                message.what = 100;
                handler.sendMessage(message);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = Message.obtain();
                message.what = 1000;
                handler.sendMessage(message);
            }
        });
    }
}
  • 点击 button1, 打印的是 ___Callback=100, 拦截了消息
  • 点击 button2, 打印的是 ___what=1000, 接收到了消息.

这是我对 Callback.handleMessage 的简单理解. 平时我们估计都不会经常用到这个 Callback, 估计一般用到的都是无参的 Handler.

本章对 Handler 的初识就到这里就结束了, 下一章会开始 Handler 对消息的发送进行分析和学习.

你可能感兴趣的:(Android 消息机制之初识Handler [ 六 ])