Handler消息机制源码解析
2016-05-26 17:15
351 查看
1.
Looper.prepareMainLooper();
ActivityThread thread = new
ActivityThread();
thread.attach(false);
if (sMainThreadHandler
== null) {
sMainThreadHandler
= thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG,
"ActivityThread"));
}
Looper.loop();
/************************************************/
public static void
prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if
(sMainLooper
!= null) {
throw new
IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper
= myLooper(); //设置主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));
}
private
Looper(boolean
quitAllowed) {
mQueue
= new
MessageQueue(quitAllowed);
mThread
= Thread.currentThread();
}
消息队列和当前线程就绑定在一起了,继续进行无限玄幻,阻塞队列,取出消息,响应消息
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;
}
msg.target.dispatchMessage(msg);
}
2. 例子:
Acitivity中实例化Handler
private
Handler mHandler
= new
Handler() {
@Override
public void
handleMessage(Message msg) {
super.handleMessage(msg);
int signal = msg.arg1;
switch (signal) {
case
0:
progressView.setProgress(0);
break;
}
}
};
点击
case
R.id.btn_enen:
Message message = new
Message();
message.arg1
= 0;
mHandler.sendMessage(message);
break;
在handler构造函数中,获取到和当前线程绑定的looper,也就是主线程的looper对象,threadlocal就是和当前线程绑定数据的工具,是与线程对应的,不同线程绑定同一个变量,只影响在当前线程的值,当前activity的handler就获得了主线程的looper对象,接下来就可以用handler发送消息了,
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
Looper myLooper() {
return
sThreadLocal.get();
}
发送消息,就是让消息进入主线程的消息队列中,有一部就是给当前handler设置给message的target变量
Handler
private boolean
enqueueMessage(MessageQueue queue,
Message msg, long
uptimeMillis) {
msg.target
= this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return
queue.enqueueMessage(msg,
uptimeMillis);
}
设置了target的handler以后,在looper.loop无限循环中,就会调用dispatchMessage()
msg.target.dispatchMessage(msg);
在dispatchMessage function调用被activity的handler复写的handleMessage(),就完成了通信,
Handler
public void
dispatchMessage(Message msg) {
if
(msg.callback
!= null) {
handleCallback(msg);
}
else {
if
(mCallback
!= null) {
if
(mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
有个地方就是如果设置了message的回调,就会执行message的回调,不会执行handleMessage(),如果没有设置message的回调,但设置了handler的callback,就会优先执行handler的callback,看返回值,如果返回true,就代表已经处理了,如果返回false,就继续执行handler的handlMessage()
private
Handler mHandler
= new
Handler(new
Handler.Callback() {
@Override
public boolean
handleMessage(Message msg) {
return false;
}
}) {
@Override
public void
handleMessage(Message msg) {
super.handleMessage(msg);
int signal = msg.arg1;
switch (signal) {
case
0:
progressView.setProgress(0);
break;
}
}
};
Looper.prepareMainLooper();
ActivityThread thread = new
ActivityThread();
thread.attach(false);
if (sMainThreadHandler
== null) {
sMainThreadHandler
= thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG,
"ActivityThread"));
}
Looper.loop();
/************************************************/
public static void
prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if
(sMainLooper
!= null) {
throw new
IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper
= myLooper(); //设置主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));
}
private
Looper(boolean
quitAllowed) {
mQueue
= new
MessageQueue(quitAllowed);
mThread
= Thread.currentThread();
}
消息队列和当前线程就绑定在一起了,继续进行无限玄幻,阻塞队列,取出消息,响应消息
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;
}
msg.target.dispatchMessage(msg);
}
2. 例子:
Acitivity中实例化Handler
private
Handler mHandler
= new
Handler() {
@Override
public void
handleMessage(Message msg) {
super.handleMessage(msg);
int signal = msg.arg1;
switch (signal) {
case
0:
progressView.setProgress(0);
break;
}
}
};
点击
case
R.id.btn_enen:
Message message = new
Message();
message.arg1
= 0;
mHandler.sendMessage(message);
break;
在handler构造函数中,获取到和当前线程绑定的looper,也就是主线程的looper对象,threadlocal就是和当前线程绑定数据的工具,是与线程对应的,不同线程绑定同一个变量,只影响在当前线程的值,当前activity的handler就获得了主线程的looper对象,接下来就可以用handler发送消息了,
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
Looper myLooper() {
return
sThreadLocal.get();
}
发送消息,就是让消息进入主线程的消息队列中,有一部就是给当前handler设置给message的target变量
Handler
private boolean
enqueueMessage(MessageQueue queue,
Message msg, long
uptimeMillis) {
msg.target
= this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return
queue.enqueueMessage(msg,
uptimeMillis);
}
设置了target的handler以后,在looper.loop无限循环中,就会调用dispatchMessage()
msg.target.dispatchMessage(msg);
在dispatchMessage function调用被activity的handler复写的handleMessage(),就完成了通信,
Handler
public void
dispatchMessage(Message msg) {
if
(msg.callback
!= null) {
handleCallback(msg);
}
else {
if
(mCallback
!= null) {
if
(mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
有个地方就是如果设置了message的回调,就会执行message的回调,不会执行handleMessage(),如果没有设置message的回调,但设置了handler的callback,就会优先执行handler的callback,看返回值,如果返回true,就代表已经处理了,如果返回false,就继续执行handler的handlMessage()
private
Handler mHandler
= new
Handler(new
Handler.Callback() {
@Override
public boolean
handleMessage(Message msg) {
return false;
}
}) {
@Override
public void
handleMessage(Message msg) {
super.handleMessage(msg);
int signal = msg.arg1;
switch (signal) {
case
0:
progressView.setProgress(0);
break;
}
}
};
相关文章推荐
- NSAttributedString
- C# 读取Excel文件里面的内容到DataSet
- 【51】java设计模式-工厂设计模式剖析
- 【51】java设计模式-工厂设计模式剖析
- yii2入门实例
- WCF添加服务失败一则
- SSRF安全威胁在JAVA代码中的应用
- JSP页面EL表达式不起效果
- soot代码分析框架的基础知识(二)
- 教师兼干部类
- Caffe在Cifar10上复现ResNet
- Background Modes in iOS Tutorial
- Java版的Redis
- linux三尖刀
- HDU_1023_Train Problem II_卡特兰数
- C++模板类的使用
- Stack的三种含义
- Adnroid ndk 中jni访问java方法、对象、成员变量
- C H A P T E R 2 9 Building a Web Services Client 29章构建一个Web Services 客户端
- 排序算法(一)---快速插入排序