枕上诗书闲处好,门前风景雨来佳。这篇文章主要讲述Android之Handler源代码深入解析相关的知识,希望能为你提供帮助。
闲着没事。就来看看源代码,看看源代码的各种原理,会用仅仅是简单的,知道为什么才是最牛逼的。
Handler源代码分析那,从使用的步骤来边用边分析:
1.创建一个Handler对象:new Handler(getMainLooper(),this);
这是我经常使用的一个方式。getMainLooper是获取主线程的Looper。this则是实现CallBack的接口
看一下Handler的构造函数
public
Handler() {
this(null,
false);
}
public
Handler(Callback callback) {
this(callback,
false);
}
public
Handler(Looper looper) {
this(looper,
null,
false);
}
public
Handler(Looper looper, Callback callback) {
this(looper, callback,
false);
}
@hide
public
Handler(boolean
async)
{
this(null,
async);
}
@hide
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;
}
@hide
public
Handler(Looper looper, Callback callback,
boolean
async)
{
mLooper
= looper;
mQueue
= looper.mQueue;
mCallback
= callback;
mAsynchronous
= async;
}
构造函数的最主要代码作用是參数的初始化赋值:
mLooper
= looper;
mQueue
= looper.mQueue;
mCallback
=
callback;
mAsynchronous
= async;
这四个參数是基本的參数了。
2.创建一个Message。
Message
msg
= handler.obtainMessage();
直接调用Handler的源代码:
public
final
Message obtainMessage()
{
return
Message.obtain(this);
}
Message中得源代码:
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();
}
这里Message是复用的概念,最大可以保持
private
static
final
int
MAX_POOL_SIZE
=
50;
50个Message的对象。
sPool变量相当于当前的空的没有被使用的Message,通过转换,将当前这个空Message给返回出去。
Message在使用完之后会被回收的。在以下会有提到。
3.给Message赋值。并发送Message :
msg.what
= 100 ;
handler.sendMessage(msg);
what是Message中得一个储值变量。
发送Message则在Handler中得终于指向是下面源代码:
private
boolean
enqueueMessage(MessageQueue queue, Message
msg,
long
uptimeMillis) {
msg.target =
this;
if
(mAsynchronous)
{
msg.setAsynchronous(true);
}
return
queue.enqueueMessage(msg, uptimeMillis);
}
oK。sendMessage给发送给了MessageQueue类。看MessageQueue怎么处理的。
boolean
enqueueMessage(Message msg,
long
when) {
?...........
if
(p ==
null
||
when == 0 || when <
p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages
= msg;
needWake =
mBlocked;
}
else
{
// Inserted within the middle of the queue.
Usually we don‘t have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake =
mBlocked
&
&
p.target ==
null
&
&
msg.isAsynchronous();
Message prev;
for
(;
;
) {
prev = p;
p = p.next;
if
(p ==
null
||
when <
p.when) {
break;
}
if
(needWake &
&
p.isAsynchronous()) {
needWake =
false;
}
}
msg.next = p;
// invariant: p == prev.next
prev.next = msg;
}
if
(needWake) {
nativeWake(mPtr);
}
}
.......
}
截取了中间重要的代码说一下。
这个是用来干嘛的??
事实上就是用来排序的,我们知道的是Message有延迟的消息,延迟消息的时间都是不一样的。when是有大小的,将后运行的Message放到后面。
MessageQueue不是使用一个集合啊或者使用数组去存放的Message,真正排序的是Message的next变量。next变量存放的是当前Message的下一个Message。
发送之后就运行了一个原生的方法nativeWake,这个在这儿就不去探究了。
4.handler消息的处理回调Callback.
public
static
void
loop()
{
........
for
(;
;
) {
Message msg = queue.next();
// might block
?
?
?.....
msg.target.dispatchMessage(msg);
?
?
?
?
??.......
msg.recycleUnchecked();
}
?
?
?......
}
这个那是Looper种的源代码。loop就是循环取MessageQueue中得Message的方法。我去掉了代码,我们能够看到调用了Messa得target变量,这个变量存放的就是Handler,dispatchMessage就是用来分发Message的方法了。看DispatchMessage的源代码:
public
void
dispatchMessage(Message
msg) {
if
(msg.callback !=
null)
{
handleCallback(msg);
}
else
{
if
(mCallback
!=
null)
{
if
(mCallback.handleMessage(msg))
{
return;
}
}
handleMessage(msg);
}
}
这个就少了非常多了啊。
看到了把,回调了callback。
这样就完毕了整个循环流程。
说一下上面的
msg.recycleUnchecked()方法。
相同,看源代码:
void
recycleUnchecked() {
// Mark the message as in use while it remains in the recycled object pool.
// Clear out all other details.
flags
=
FLAG_IN_USE;
what
= 0;
arg1
= 0;
arg2
= 0;
obj
=
null;
replyTo
=
null;
sendingUid
= -1;
when
= 0;
target
=
null;
callback
=
null;
data
=
null;
synchronized
(sPoolSync)
{
if
(sPoolSize
<
MAX_POOL_SIZE)
{
next
=
sPool;
sPool
=
this;
sPoolSize++;
}
}
}
从方法名上能够知道这个是用来回收Message的。
在Message使用完成之后,不是将MEssage对象销毁,而是存放起来,将其下次反复使用。
Handler执行大概流程就是这种了。
Looper的类的源代码分析,回头再解析。
android开发交流群:417270671
我的github地址:
https://github.com/flyme2012
【Android之Handler源代码深入解析】
推荐阅读
- Android项目实战_手机安全卫士系统加速
- Android中使用SQLite
- Android开发之BUG专讲(入门篇)
- Spring MVC 常用注解@Controller,@RequestMapping,Model和ModelAndView
- apply,call,bind
- android数据储存之存储方式
- Android React Native 开发环境搭建---windows下
- 如何高效地分析Android_log中的问题(——查看Android源码)
- 视频零基础学Android开发(蓝牙聊天室APP)