handler机制的源码分析
来源:互联网 发布:递归算法经典实例 java 编辑:程序博客网 时间:2024/05/11 06:00
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));
}
ThreadLocal类似Map,调用sThreadLocal.set(Object obj)方法,以当前线程对象为键,obj为值存入sThreadLocal中。而这里是new了一个Looper对象作为值存入。
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
从上面的构造函数可以看出,生成Looper对象的同时,又生成了一个与之对应的mQueue,得到了当前线程mThread。
sThreadLocal是静态变量,所以无论有多少个线程对象和looper,都能存入到同一个sThreadLocal中。一个键对应一个值,所以一个线程对应唯一的一个looper。
sThreadLocal.get() ,以当前线程为键,取出之前存入的对应的looper。
handler = new Handler();
public Handler() {
this(null, false);
}
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;
}
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
执行myLooper() 方法实际上就是返回了之前在looper.prepare()中存入sThreadLocal的looper,这里把这个looper赋值给了Handler的成员变量mLooper。
上面在存入looper的时候是new了一个Looper,并且还生成了一个与之对应的mQueue。mQueue = mLooper.mQueue这句代码就是把mQueue赋值给Handler的成员变量mQueue。
至此,mLooper mQueue handler mThread就联系起来了。
Looper.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
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
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();
}
}
final Looper me = myLooper();获取到当前线程对应的Looper对象
final MessageQueue queue = me.mQueue;获取到与Looper对象对应的MessageQueue对象
for(;;)相当于while(sure),在遇到break之前是死循环。代码块的作用是循环从消息队列取消息。
Message msg = queue.next(); next()方法返回值类型是Message,所以这里的意思是从消息队列中取出数据。如果没有消息,就会阻塞,直到又有消息。
msg.target.dispatchMessage(msg);
Message msg = handler.obtainMessage();
public final Message obtainMessage()
{
return Message.obtain(this);
}
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
实际上,m.target = handler msg.target.dispatchMessage(msg)相当于handler.dispatchMessage(msg)
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
- handler机制的源码分析
- Handler机制.源码分析
- Handler 机制 源码分析
- 源码分析Handler机制
- Handler消息机制的源码分析
- handler ,Looper的机制,分析源码。
- Handler消息机制的源码分析
- Handler消息机制源码分析
- Handler 机制-源码分析
- handler机制原理源码分析
- Android Handler机制源码分析
- handler机制 源码分析 梳理
- Android基于源码分析Handler的消息机制
- Android 消息机制 - Handler, Looper, Message, MessageQueue 的源码分析
- Handler异步消息处理机制的源码分析
- 从源码分析Android中Handler的消息传递机制
- 深入源码分析Handler的消息处理机制
- Android源码分析--Handler机制的实现与工作原理
- 百度阅读搜索_android
- Android中处理崩溃异常 Android捕获全局异常信息并实现上传
- Android Studio实用指南
- tomcat启动报错java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException?
- 配置sql输出
- handler机制的源码分析
- Android 读写文件
- Linux 密钥远程登陆主机
- Yeoman搭建
- cannot convert from android.app.FragmentManager to android.support.v4.app.FragmentManager
- fftw的使用
- XML基础阶段小结
- 40个妙趣横生的404页面
- golang x/net/context包笔记