1. Handle中的属性:

    final Looper mLooper;
final MessageQueue mQueue;
final Callback mCallback;
final boolean mAsynchronous;
IMessenger mMessenger;

   mQueue消息队列,拥有消息队列的引用,handle可以对已发送的消息或任务再进行取消操作,如下源码:

  public final void removeMessages(int what) {
  mQueue.removeMessages(this, what, null);
  }
  public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
} /**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}

往消息队列中添加消息:

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this; //Message中记录了来自哪个handle
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}

2.Handle中的初始化:

  通常我们使用的方式是 Handle handle=new Handle();这一过程执行的代码是:

  

   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) == ) {
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中拿到looper和MessageQueue的引用赋值给Handler中的变量,MessageQueue和Looper的创建是在looper中完成的。

3.Looper:

  1)主要的属性:

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;

  2)构造函数:

  对MessageQueue和mThread进行了初始化

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

  3)prepare()方法:中对Looper进行了构建;并存放在ThreadLocal中。

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

   ※static final ThreadLocal<Looper> 可知线程本地变量是静态final 类型的 整个进程中只有一份,里面存储 各个线程的Looper,存储方式类似于键(thread)值(looper)的方式。

  4)looper():

    

   /**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
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 block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
} // This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
} final long traceTag = me.mTraceTag;
if (traceTag != && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != ) {
Trace.traceEnd(traceTag);
}
} if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
} // Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
} msg.recycleUnchecked();
}
}

    这里有个循环 不断监控mQueue中的消息,有消息了 就取出 交给Handle处理;

  5)。Thread TheadLocal  ThreadLocalMap;

    ThreadLocalMap是TheadLocal的内部类,ThreadLocalMap是Thread的成员变量;Loop.prepare()里面,ThreadLocal负责将Looper对象存储到Thread的ThreadLocalMap中;

主线程的Looper初始化:

  源码的位置是在ActivityThread类中的main函数。

  

public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();//这实际就是一个实例化一个looper对象,大家也可以看看prepareMainlooper方法(下方)。
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();//启动循环器

  

Handle/Looper源码分析;的更多相关文章

  1. 【Android】Handler、Looper源码分析

    一.前言 源码分析使用的版本是 4.4.2_r1. Handler和Looper的入门知识以及讲解可以参考我的另外一篇博客:Android Handler机制 简单而言:Handler和Looper是 ...

  2. Handler、Looper、MessageQueue、Thread源码分析

    关于这几个之间的关系以及源码分析的文章应该挺多的了,不过既然学习了,还是觉得整理下,印象更深刻点,嗯,如果有错误的地方欢迎反馈. 转载请注明出处:http://www.cnblogs.com/John ...

  3. Android源码分析-消息队列和Looper

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17361775 前言 上周对Android中的事件派发机制进行了分析,这次博主 ...

  4. Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue

    android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...

  5. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

  6. Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建

    Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...

  7. Android消息机制源码分析

    本篇主要介绍Android中的消息机制,即Looper.Handler是如何协同工作的: Looper:主要用来管理当前线程的消息队列,每个线程只能有一个Looper Handler:用来将消息(Me ...

  8. Android7.0 Phone应用源码分析(二) phone来电流程分析

    接上篇博文:Android7.0 Phone应用源码分析(一) phone拨号流程分析 今天我们再来分析下Android7.0 的phone的来电流程 1.1TelephonyFramework 当有 ...

  9. 源码分析Android Handler是如何实现线程间通信的

    源码分析Android Handler是如何实现线程间通信的 Handler作为Android消息通信的基础,它的使用是每一个开发者都必须掌握的.开发者从一开始就被告知必须在主线程中进行UI操作.但H ...

随机推荐

  1. 学习笔记DL005:线性相关、生成子空间,范数,特殊类型矩阵、向量

    线性相关.生成子空间. 逆矩阵A⁽-1⁾存在,Ax=b 每个向量b恰好存在一个解.方程组,向量b某些值,可能不存在解,或者存在无限多个解.x.y是方程组的解,z=αx+(1-α),α取任意实数. A列 ...

  2. jmeter简单的接口性能测试

    原文转自:https://blog.csdn.net/lovesoo/article/details/78579547 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件 ...

  3. git 之路

    1. 不要把配置文件放到你的 Git 代码仓库 https://www.oschina.net/translate/dont-include-configs-in-your-git-repos 2. ...

  4. 类似py2exe软件真的能保护python源码吗

    类似py2exe软件真的能保护python源码吗 背景 最近写了个工具用于对项目中C/C++文件的字符串常量进行自动化加密处理,用python写的,工具效果不错,所以打算在公司内部推广.为了防止代码泄 ...

  5. day-07数据类型转换与字符编码

    类型转换 1.字符串转换为数字 res = int('10')print(res)res = int('-3')print(res)res = float('.15')print(res)res = ...

  6. c++——智能指针学习(unique_ptr)

    1.为什么会有unique_ptr? 动态内存忘记delete,导致内存泄漏.比如: p = new (); if(...) { return ; } delete p; 因此我们需要一种方式来解决这 ...

  7. node.js 远程调试debug产线环境代码

    一.背景: 产线机器出bug,不能重启服务,需要保留现场,问题不好排查,只能靠远程debug. 二.实现步骤 1. 登录远程机器执行如下命令,nodePid为node服务的pid kill -usr1 ...

  8. 采用Anaconda平台调用pymc3时出现错误的解决方法

    提示:(1)module 'theano' has no attribute 'gof',c++编辑出现错误 (2)stdio.h file not found 解决方法:(1)在终端中输入 xcod ...

  9. 黑电平校正BLC

    参考:https://www.cnblogs.com/zhangAlin/p/10661763.html

  10. 使用velodyne16线激光雷达跑loam-velodyne

    一.velodyne-VLP16使用教程 推荐网址: http://blog.csdn.net/littlethunder/article/details/51920681 https://www.c ...