志不强者智不达,言不信者行不果。这篇文章主要讲述Android源码学习 Handler相关的知识,希望能为你提供帮助。
Handler的实例化
在安卓开发中,经常会用到Handler将任务提交到指定线程(例如主线程)去执行或者让其延迟执行。Handler的构造函数有多种重载形式,但最终都调用到如下两种之一:
public Handler(Callback callback, boolean async) { mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can‘t create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
【Android源码学习 Handler】可以看到:这两个构造函数的区别只是Looper的获取方式不一样,当未指定Looper时,Handler内部会通过Looper.myLooper()静态方法,获取当前线程的Looper。我们往Handler上发送的Message或者Runnable正是由这个Looper(或该Looper的线程)负责处理的。我们可以通过Looper.getMainLooper()获取主线程的Looper。
发送Message或者Runnable
调用post、postAtTime、postDelayed提交Runnable,调用sendMessage、sendEmptyMessage、sendMessageDelayed、sendEmptyMessageDelayed、sendMessageAtTime、sendEmptyMessageAtTime发送Message,最终都调用到sendMessageAtTime:
1 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 2MessageQueue queue = mQueue; 3if (queue == null) { 4RuntimeException e = new RuntimeException( 5this + " sendMessageAtTime() called with no mQueue"); 6Log.w("Looper", e.getMessage(), e); 7return false; 8} 9return enqueueMessage(queue, msg, uptimeMillis); 10 } 11 12 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 13msg.target = this; 14if (mAsynchronous) { 15msg.setAsynchronous(true); 16} 17return queue.enqueueMessage(msg, uptimeMillis); 18 }
也就是说,提交的Runnable最终会被包装成Message,此时Message的callback字段将指向该Runnable。所有提交的Message都将会被插入名为mQueue的有序队列中,排序的依据便是传入的uptimeMillis(该值在enqueueMessage操作中会被赋给Message的when字段)。MessageQueue使用生产者-消费者模式,post*和send*产生的消息,最终会被Looper消费。(第2行中将mQueue赋给局部变量queue再通过改变访问mQueue,显然是出于多线程并发的安全性考虑)
使用postAtFrontOfQueue、sendMessageAtFrontOfQueue可以分别提交Runnable和Message到mQueue的队首,该Runnable或者Message将在Looper的下次循环中处得到处理。
使用removeCallbacks、removeMessages、removeCallbackAndMessages可以移除掉已经提交的Runnable或者Message。
推荐阅读
- 02 Django框架基础(APP的创建访问)
- Android快速开发常用知识点系列目录
- 手机APP ~ MUI——创建页面方法
- appium-andriod自动化实现注意项
- jpush-react-native 推送功能(Android 篇)
- ReactNative 调用手机地图(高德百度)导航 Android
- Android中数据存储——ContentProvider存储数据
- Android中数据存储——SQLite数据库存储数据
- android应用名称设置的问题