写点什么

浅谈 -Android-Handler,h5 移动端开发面试题

用户头像
Android架构
关注
发布于: 1 小时前

Values?values?=?values(currentThread);if?(values?!=?null)?{Object[]?table?=?values.table;int?index?=?hash?&?values.mask;if?(this.reference?==?table[index])?{return?(T)?table[index?+?1];}}?else?{values?=?initializeValues(currentThread);}


return?(T)?values.getAfterMiss(this);}



get 方法就是取出当前线程对应的 looper,也就是说 ThreadLocal 是负责 thread 和 looper 之间的关系的


下面看一下 Looper.prepare()方法


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));}


默认情况下 ThreadLocal 是没有存储的,所以要创建一个新的 looper


private?Looper(boolean?quitAllowed)?{mQueue?=?new?MessageQueue(quitAllowed);mThread?=?Thread.currentThread();}



默认情况下 ThreadLocal 是没有存储的,所以要创建一个新的 looper


private?Looper(boolean?quitAllowed)?{mQueue?=?new?MessageQueue(quitAllowed);mThread?=?Thread.currentThread();}


![image.gif](https://upload-images.jianshu.io/upl


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


oad_images/15233854-8187e19d407873b6.gif?imageMogr2/auto-orient/strip)


从 looper 方法中,创建了一个 MessageQueue,在 looper 中维护着一个消息队列


知道了 looper 和 MessageQueue 之后,究竟 handler 跟这两者有什么关系呢,继续看源码


public?Handler(Callback?callback,?boolean?async)?{if?(FIND_POTENTIAL_LEAKS)?{final?Class<??extends?Handler>?klass?=?getClass();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());}}


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;}



首先调用 Looper.myLooper()


public?static?@Nullable?Looper?myLooper()?{return?sThreadLocal.get();}



获得当前的 looper 对象,通过 looper 拿到 MessageQueue,就完成了 handler 和 looper 之间的关联


下面继续看 handler 的消息发送


public?boolean?sendMessageAtTime(Message?msg,?long?uptimeMillis)?{MessageQueue?queue?=?mQueue;if?(queue?==?null)?{RuntimeException?e?=?new?RuntimeException(this?+?"?sendMessageAtTime()?called?with?no?mQueue");Log.w("Looper",?e.getMessage(),?e);return?false;}return?enqueueMessage(queue,?msg,?uptimeMillis);}



先获得当前的消息队列,如果队列为空就抛出异常,不为空,向消息队列中插入消息


private?boolean?enqueueMessage(MessageQueue?queue,?Message?msg,?long?uptimeMillis)?{msg.target?=?this;if?(mAsynchronous)?{msg.setAsynchronous(true);}return?queue.enqueueMessage(msg,?uptimeMillis);}



插入消息之前就指定消息发送给谁(msg.target),默认情况下发送给自己的 handler,然后把消息放入队列中,handler 就完成了发送 message 到 MessageQueue 的过程


那么消息又是如何轮询的呢?


public?static?void?loop()?{final?Looper?me?=?myLooper();if?(me?==?null)?{throw?new?RuntimeException("No?Looper;?Looper.prepare()?wasn't?called?on?this?thread.");}final?MessageQueue?queue?=?me.mQueue;


//?Make?sure?the?identity?of?this?thread?is?that?of?the?local?process,//?and?keep?track?of?what?that?identity?token?actually?is.Binder.clearCallingIdentity();final?long?ident?=?Binder.clearCallingIdentity();


for?(;;)?{Message?msg?=?queue.next();?//?might?blockif?(msg?==?null)?{//?No?message?indicates?that?the?message?queue?is?quitting.return;}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
浅谈-Android-Handler,h5移动端开发面试题