Handler Looper MessageQueue Message
1.Handler的机制流程
如果在主线程中new Handler,Activity创建的时候会创建Looper,创建Looper的时候会创建MessageQueue,通过looper.mQueue()能得到MessageQueue对象,如果不是在主线程中new Handler就需要 通过Looper.prepare() 来初始化looper。当Handler.sendMessage(Message)到MessageQueue,该函数里面设置了那个Message对象的target属性是当前Handler对象,然后looper.prepare初始化looper,通过looper.mQueue获取MessageQueue对象,looper.loop 是一个轮询MessageQueue对象的方法,loop会获取MessageQueue对象的next方法来对消息队列进行轮询Message,MessageQueue是先进先出原则,
loop方法:
public static void loop() {
final Looper me = myLooper(); //myLooper返回当前线程的Looper对象
final MessageQueue queue = me.mQueue; // 取出Looper中的消息队列
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
...
//quit
return;
}
...
// 调用该消息的Handler,交给它的dispatchMessage处理
msg.target.dispatchMessage(msg);
...
// 消息的回收,回收到消息池中。
msg.recycle();
}
(MessageQueue最主要的两个方法 enqueueMessage和 next 插入和读取两个操作,读取同时会删除Message,enqueueMessage方法源码了解到是一个单链表的插入操作,next是一个无限循环的方法如果没有消息,则会阻塞在这里,如果有消息则会返回,并且从链表删除)Message msg = queue.next(); 这是looper中loop方法中的代码,获取的Message,如果获取到则调用hander的dispatchMessage处理。具体例子可以参照子线程中更新ui
2.Handler 和Looper的同步关系?引出ThreadHandler
package com.zhy.blogcodes.intentservice;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.widget.TextView;
import com.zhy.blogcodes.R;
public class HandlerThreadActivity extends AppCompatActivity{
private TextView mTvServiceInfo;
private HandlerThread mCheckMsgThread;
private Handler mCheckMsgHandler;
private boolean isUpdateInfo;
private static final int MSG_UPDATE_INFO = 0x110; //与UI线程管理的handler
private Handler mHandler = new Handler();
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thread_handler);
//创建后台线程 initBackThread();
mTvServiceInfo = (TextView) findViewById(R.id.id_textview);
}
@Override protected void onResume() {
super.onResume(); //开始查询 isUpdateInfo = true;
mCheckMsgHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
@Override protected void onPause() {
super.onPause(); //停止查询
isUpdateInfo = false;
mCheckMsgHandler.removeMessages(MSG_UPDATE_INFO);
}
private void initBackThread() {
mCheckMsgThread = new HandlerThread("check-message-coming");
mCheckMsgThread.start();
mCheckMsgHandler = new Handler(mCheckMsgThread.getLooper())
{
@Override public void handleMessage(Message msg) {
checkForUpdate();
if (isUpdateInfo) {
mCheckMsgHandler.sendEmptyMessageDelayed(MSG_UPDATE_INFO, 1000);
} }
}; }
/** * 模拟从服务器解析数据 */
private void checkForUpdate() {
try {
//模拟耗时 Thread.sleep(1000);
mHandler.post(new Runnable() {
@Override public void run() {
String result = "实时更新中,当前大盘指数:<font color='red'>%d</font>";
result = String.format(result, (int) (Math.random() * 3000 + 1000));
mTvServiceInfo.setText(Html.fromHtml(result)); } }); }
catch (InterruptedException e) { e.printStackTrace(); } }
@Override protected void onDestroy() {
super.onDestroy(); //释放资源
mCheckMsgThread.quit(); }}
ThreadHandler与Thread之间的差别,唯一区别是ThreadHandler中有looper 的创建以及MessageQueue的消息队列,不断的轮询队列中的消息
使用ThreadHandler threadHandler=new ThreadHandler("test handler");
threadHandler.start();
new Handler(thread.getLooper()){
};
一个handler对应一个线程,这个线程不是主线程,所有可以再handlerMessage中做耗时操作,但是一般的Handler就不可以。
3.Handler 使用如何会导致内存泄漏及解决方案?