Handler机制原理解析(二)prepare,loop,post
Handler机制原理解析(二)prepare,loop,post
上一篇已经介绍了Handler机制的原理,如果不熟悉可以看Handler机制原理解析(一)。这一篇,介绍下Handler周边的知识点。我们已经知道,要获得looper对象,必须要先执行prepare。
1,Looper.prepare
public static void prepare() {prepare(true);}private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}/*** Initialize the current thread as a looper, marking it as an* application's main looper. The main looper for your application* is created by the Android environment, so you should never need* to call this function yourself. See also: {@link #prepare()}*/public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}}
从prepareMainLooper的注释我们能看到,初始化当前线程为looper,并且标记为应用的主looper,这个主looper是Android帮忙创建的,所有不需要手动调用。我们跟踪这个方法。在ActivityThread中我们看到
public static void main(String[] args) {....Looper.prepareMainLooper();....Looper.loop();....
}
这里我们只需知道,这个方法会在创建应用的时候调用,并且在主Activity的onCreate前已经调用了即可。至于Activity的启动流程,这里不做详述。这里我们同时也看到了另外一个方法,loop。需要注意的是,如果想在工作线程使用Handler,需要手动调用这两个方法,至于顺序,相信你一定知道。
2,post(Runnable)
public final boolean post(Runnable r){return sendMessageDelayed(getPostMessage(r), 0);}
只有这一句,接着看吧,先看getPostMessage
private static Message getPostMessage(Runnable r) {Message m = Message.obtain();m.callback = r;return m;}
这里将Runnable对象r封装进Message对象了。后面就不用再分析了,因为现在已经变成了send(message),前面我们说过,最终都会调用到一个方法上。发送是相同的,可是处理是不同的。还是贴一下处理的代码吧
public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}
如果是发送的runnable,则会走第一个分支
private static void handleCallback(Message message) {message.callback.run();}
这里也没啥,就是让其run起来。再回顾一下,无论在哪个线程post一个Runnable,最终都是会通过dispatch方法,让其run起来,而我们知道,dispatch方法是在主线程。那么View的post方法呢,应该也是封装了Handler的post吧,我们一起看看
public boolean post(Runnable action) {final AttachInfo attachInfo = mAttachInfo;if (attachInfo != null) {return attachInfo.mHandler.post(action);}// Postpone the runnable until we know on which thread it needs to run.// Assume that the runnable will be successfully placed after attach.getRunQueue().post(action);return true;}
先看第一个分支,如果有attachinfo,就通过handler post出去。这个应该跟handler的方法一样。
/*** A Handler supplied by a view's {@link android.view.ViewRootImpl}. This* handler can be used to pump events in the UI events queue.*/final Handler mHandler;
看一下Handler,果然一样。这种是view已经attach到window上了,如果没有呢?看另一个分支
public void post(Runnable action) {postDelayed(action, 0);}public void postDelayed(Runnable action, long delayMillis) {final HandlerAction handlerAction = new HandlerAction(action, delayMillis);synchronized (this) {if (mActions == null) {mActions = new HandlerAction[4];}mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);mCount++;}}
这里还是不清楚,继续往下看
public static <T> T[] append(T[] array, int currentSize, T element) {assert currentSize <= array.length;if (currentSize + 1 > array.length) {@SuppressWarnings("unchecked")T[] newArray = ArrayUtils.newUnpaddedArray((Class<T>) array.getClass().getComponentType(), growSize(currentSize));System.arraycopy(array, 0, newArray, 0, currentSize);array = newArray;}array[currentSize] = element;return array;}
这里能看明白,就是把handlerAction加入到数组中了(Runnable封装在handlerAction中)。这似乎也没得到执行啊。确实
,没办法,既然有post方法,我们姑且尝试看看有没有handle什么之类名字的方法吧。
public void executeActions(Handler handler) {synchronized (this) {final HandlerAction[] actions = mActions;for (int i = 0, count = mCount; i < count; i++) {final HandlerAction handlerAction = actions[i];handler.postDelayed(handlerAction.action, handlerAction.delay);}mActions = null;mCount = 0;}}
果不其然,能executeAction,并且通过handler post出去了,猜测应该没问题,那就往上找找看吧。在View的dispatchAttachedToWindow中调用的
if (mRunQueue != null) {mRunQueue.executeActions(info.mHandler);mRunQueue = null;}
哦,原来当view被attach到window上时,就可以通过handler post出去了。其实呢,跟View post方法的第一个分支一样,只不过保证view一定要执行过attach。
Handler机制原理解析(二)prepare,loop,post相关推荐
- Handler机制原理解析(一)
Handler机制原理解析(一) 我们都知道,在Android中,主线程也叫UI线程是负责界面更新的,子线程或者工作线程适合做网络请求,数据库等耗时操作.如果在主线程中执行耗时操作可能引发ANR异常. ...
- android Handler机制原理解析(一篇就够,包你形象而深刻)
首先,我将Handler相关的原理机制形象的描述为以下情景: Handler:快递员(属于某个快递公司的职员) Message:包裹(可以放置很多东西的箱子) MessageQueue:快递分拣中心( ...
- AsyncTask机制原理解析
AsyncTask机制原理解析 Android为我们提供了2种方便的异步处理方案,Handler和AsyncTask,两种方式适合的场景网上一搜就知道了,但是为什么呢?这篇分析将为你揭晓答案.前面分析 ...
- Binder通信机制原理解析
Binder是什么?Binder有啥用?作为一个应用开发者,如果我们开发的应用不涉及跨进程通信(IPC),我想我们也不会去接触Binder.但不知你有没有发现,近来的Andorid面试,都会问及And ...
- OkHttp原理解析(二)
前言 上一篇我们学习了OKHttp的请求执行流程,知道了最终请求流程都会交给getResponseWithInterceptorChain方法来执行,接下来我们就详细分析执行getResponseWi ...
- python解析原理_Python语法垃圾回收机制原理解析
一 引入 解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那 ...
- Android实战开发Handler机制深度解析
本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助. 本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/gedu ...
- RCU锁机制原理解析
背景 为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁(rwlock),它们使用起来非常简单,而且是一种很有效的同步机制,在UNIX系统和Linux系统中得到了广泛的使用.但是 ...
- Hadoop的HA机制原理解析,与HA高可用集群环境搭建
2019独角兽企业重金招聘Python工程师标准>>> Hadoop的HA工作机制示意图 下面我们开始搭建这一套高可用集群环境 hadoop2.0已经发布了稳定版本了,增加了很多特性 ...
最新文章
- 用c++写一个猜数字的小游戏
- STM32开发 -- 复位类型判断
- ITK:用高斯核计算平滑
- bzoj1556 (DP)
- spring3: AOP 之 6.2 AOP的HelloWorld
- 谈谈 SAP 系统的权限管控和事务记录功能的实现
- java+webrtc+回声消除,WebRTC回声消除(2)
- opencv+映美相机,从缓冲区中抓图片或者显示视频
- 版本控制软件 perforce 与 git
- python让solidworks自动建模_让机器学习自动帮我们建模,这4个Python库能让你大开眼界...
- Postgres-XL集群的搭建和测试详解
- RGB Triplets(后缀和)
- python f检验 模型拟合度_python 线性回归分析模型检验标准--拟合优度详解
- PowerMockito Mock私有方法
- 如何在Mercurial中编辑错误的提交消息? [重复]
- 一键如何完成多张静态图合成GIF图?
- 【安卓-tio】安卓集成t-io
- linux systat安装包,Linux下sysstat 安装
- promentheus的组件有_四级考试写作:书信类话题范文模板
- linux运维-dovecot+postfix和空壳邮件
热门文章
- DVWA关卡3:Cross Site Request Forgery (CSRF)(跨站请求伪造)
- 数据结构-顺序表基本操作(C语言实现)
- SQL developer 4运行ASH
- Linux初学者学习方法
- IAR的一个编译错误Error[e27]: Entry GenericApp_Init::?relay in module Coordinator
- 4.思科路由器基本配置及排除题目练习
- OpenCV 图像轮廓检测
- 穷举算法(鸡兔同笼问题)
- Python while循环
- 0731-并查集-HDU2473