异步消息机制

1.  一个线程里面只有一个Looper。

2. 子线程也可创建handler。

前后需分别加上Looper.prepare();和Looper.loop();

标准写法:

Looper.prepare();

Handler mHandler = new Handler() {

@Override

publicvoidhandleMessage(Message msg) {

if (msg.what == 10000) {

Log.i(TAG,"在子线程中定义Handler,并接收到消息。。。");

}

}};

Looper.loop();

prepare 中创建looper。

3. 主线程对应的方法在ActivityThread的main方法中。

4. Looper的构造方法中初始化了一个MessageQueue对象

privateLooper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mThread = Thread.currentThread();

}

总:Looper.prepare()方法初始话了一个Looper对象并关联在一个MessageQueue对象,并且一个线程中只有一个Looper对象,只有一个MessageQueue对象。而Handler的构造方法则在Handler内部维护了当前线程的Looper对象

5. handler.sendMessage(msg) 会调用queue.enqueueMessage(msg, uptimeMillis);,会发现 MessageQueue并没有使用列表将所有的Message保存起来,而是使用Message.next保存下一个Message,从而按照时间将所有的Message排序;

6. Looper.loop()

可以看到Looper.loop()方法里起了一个死循环,不断的判断MessageQueue中的消息是否为空,如果为空则直接return掉,然后执行queue.next()方法

可以看到其大概的实现逻辑就是Message的出栈操作,里面可能对线程,并发控制做了一些限制等。获取到栈顶的Message对象之后开始执行:

msg.target.dispatchMessage(msg);

Handle的dispatchMessage()

/**  

* Handle system messages here. */

publicvoiddispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

}else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

 }

handleMessage(msg);

}

}

可以看到,如果我们设置了callback(Runnable对象)的话,则会直接调用handleCallback方法:

privatestaticvoidhandleCallback(Message message) {

message.callback.run();

}

msg.callback为空的话,会直接调用我们的mCallback.handleMessage(msg),即handler的handlerMessage方法。由于Handler对象是在主线程中创建的,所以handler的handlerMessage方法的执行也会在主线程中


原作者的总结:

1)主线程中定义Handler,直接执行:

Handler mHandler =new Handler() {

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

}};

而如果想要在子线程中定义Handler,则标准的写法为:

// 初始化该线程Looper,MessageQueue,执行且只能执行一次

Looper.prepare();

// 初始化Handler对象,内部关联Looper对象

Handler mHandler =new Handler() {

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

}

};

// 启动消息队列出栈死循环

Looper.loop();

2)一个线程中只存在一个Looper对象,只存在一个MessageQueue对象,可以存在N个Handler对象,Handler对象内部关联了本线程中唯一的Looper对象,Looper对象内部关联着唯一的一个MessageQueue对象。

3)MessageQueue消息队列不是通过列表保存消息(Message)列表的,而是通过Message对象的next属性关联下一个Message从而实现列表的功能,同时所有的消息都是按时间排序的。

4)android中两个子线程相互交互同样可以通过Handler的异步消息机制实现,可以在线程a中定义Handler对象,而在线程b中获取handler的引用并调用sendMessage方法。

5)activity内部默认存在一个handler的成员变量,android中一些其他的异步消息机制的实现方法: 
Handler的post方法:

mHandler.post(new Runnable() {

@Override

publicvoidrun() {

}

});

查看其内部实现:

publicfinalbooleanpost(Runnable r) {

return sendMessageDelayed(getPostMessage(r), 0);

}

可以发现其内部调用就是sendMessage系列方法。。。

view的post方法:

publicbooleanpost(Runnable action) {

final AttachInfo attachInfo = mAttachInfo;

if (attachInfo != null) {

return attachInfo.mHandler.post(action);

}

// Assume that post will succeed later

ViewRootImpl.getRunQueue().post(action);

returntrue;

}

可以发现其调用的就是activity中默认保存的handler对象的post方法。

activity的runOnUiThread方法:

publicfinalvoidrunOnUiThread(Runnable action) {

if (Thread.currentThread() != mUiThread) {

mHandler.post(action);

}else {

action.run();

}

}

判断当前线程是否是UI线程,如果不是,则调用handler的post方法,否则直接执行run方法。

http://blog.youkuaiyun.com/qq_23547831/article/details/50751687


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值