首先简单介绍以下Handler的机制
Message
Message是在线程之间传递的消息,用于在不同线程之间交换数据。
Handler
Handler主要用于发送和处理消息。发送消息一般使用Handler的sendMessage()方法,发送的消息最终传递到Handler的handleMessage()方法中。
MessageQueue
MessageQueue为消息队列,主要用于存放所有通过Handler发送的消息。消息存储于消息队列中等待被处理。每个线程中只有一个MessageQueue对象。
Looper
Looper是每个线程的MessageQueue的管家,调用Looper的loop()方法之后,会进入一个无限循环中,每当发现MessageQueue中存在一条等待处理的消息,就会将它取出,传递到Handler的handleMessage()方法中。每个线程中只有一个Looper对象。
Handler机制
异步处理消息流程:
1.在主线程中创建一个Handler对象,并重写handleMessage方法。
2.子线程创建一个Message对象,通过Handler将这条消息发送出去(调用sendMessage()方法)。
3.消息被添加到MessageQueue的队列中等待处理,Looper一直尝试从MessageQueue取出等待处理的消息,交给Handler的handleMessage()方法中。
Android中主线程一直查看消息为什么不会阻塞
处理消息的时候使用了Looper.loop()方法,该方法被主线程调用,且该方法中存在一个死循环在遍历消息队列取消息,为什么没有被阻塞呢?
1.Android程序启动的入口android.app.ActivityThread类的main()方法
public static final void main(String[] args){
...
//当前主线程消息循环
Looper.loop();
...
}
Looper.loop()方法:
public static final void loop(){
...
//死循环
while(true){
...
}
...
}
2.ActivityThread并不是一个线程,只是一个final类,主线程就从这个类的main方法开始。里面就有调用Looper的loop方法。
3.看看下面handleMessage的代码:
ActivityThread有一个getHandler方法,得到handler可以发送消息;
然后loop分发消息,发给handler;
然后执行Handler中的对应代码。
有消息过来才可以执行所以不会发生卡死
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case PAUSE_ACTIVITY_FINISHING:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&1) != 0);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case STOP_ACTIVITY_SHOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
handleStopActivity((IBinder)msg.obj, true, msg.arg2);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case STOP_ACTIVITY_HIDE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
handleStopActivity((IBinder)msg.obj, false, msg.arg2);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SHOW_WINDOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
handleWindowVisibility((IBinder)msg.obj, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case HIDE_WINDOW:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
handleWindowVisibility((IBinder)msg.obj, false);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case RESUME_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SEND_RESULT:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
handleSendResult((ResultData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}