Android中主线程一直查看消息为什么不会卡死

首先简单介绍以下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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42882887/article/details/86566528
今日推荐