Handler Looper Message的源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mChenys/article/details/85261896

Handler

Handler是用来分发和处理消息的,通常我们创建Handler都是使用其无参数的构造方法


public Handler() {
    this(null, false);
}

其内部调用的是2个参数的构造方法


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) {
          	//大概的意思就是创建Handler的匿名内部类,成员类,局部类的时候会给出下面log的提示
             Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                 klass.getCanonicalName());
         }
     }
	 //获取当前线程的Looper对象,如果是在UI线程(四大组件)中创建Handler,那么这里拿到的就是主线程的Looper
     mLooper = Looper.myLooper();
     if (mLooper == null) {
     	//在子线程中创建Handler如果没有事先初始化Looper,是拿不到Looper的,因此会抛异常
         throw new RuntimeException(
             "Can't create handler inside thread that has not called Looper.prepare()");
     }
     //记录Looper对象内的MessageQueue消息队列
     mQueue = mLooper.mQueue;
     //记录传递进来的callback接口,注意这里的Callback接口是定义在Handler类内部的.
     mCallback = callback;
     //记录是否是异步,默认构造方法传入的是false,表示同步处理消息
     mAsynchronous = async;
 }

//内部接口
public interface Callback {
    public boolean handleMessage(Message msg);
}

分析上面的源码可以发现,在new Handler的时候,内部会得到一个Looper对象,以及该Looper的MessageQueue对象.
同时提到了 "Can't create handler inside thread that has not called Looper.prepare()");这个异常,仅当Looper获取为空的时候抛出.

另外,参数async表示此创建的Handler是否用于处理异步消息,如果是则需要通过Message的方式来异步处理,而如果不是,那就通过postRunnable的方式来处理同步的消息.


Looper

上面创建handler的时候提到了Looper,那么现在我们来分析下Looper的源码

public final class Looper {
    private static final String TAG = "Looper";

    // 通过ThreadLocal绑定Looper对象到当前线程,默认情况下sThreadLocal.get()会返回null,除非你事先调用了prepare()方法.
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    // 主线程的Looper对象,在主线程中创建Handler,默认会初始化一个Looper与主线程绑定
    private static Looper sMainLooper; 
	//消息队列,每个Looper对象内部都有一个消息队列
    final MessageQueue mQueue;
    //当前线程
    final Thread mThread;
	//log输出对象
    private Printer mLogging;

     /** 
     * 初始化Looper,给当前线程绑定一个Looper对象,该方法创建的Looper,默认是支持结束loop的
      */
    public static void prepare() {
        prepare(true);
    }
	/**
	* 私有的初始化Looper对象方法
	* 参数quitAllowed表示是否支持结束loop,通过调用quit()或者quitSafely()方法进行结束
	*/
    private static void prepare(boolean quitAllowed) {
    	//一个线程只能绑定一次Looper
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //创建一个Looper,并将Looper绑定到当前线程中
        sThreadLocal.set(new Looper(quitAllowed));
    }
	
	/**
	* 私有构造方法,因此创建Looper必须要通过prepare方法创建
	*/
	private Looper(boolean quitAllowed) {
		//初始化该Looper的MessageQueue对象,Handler发送消息的时候会用到mQueue,它用于存储Handler发送的Message
        mQueue = new MessageQueue(quitAllowed);
        //获取当前线程,作为sThreadLocal的key,value就是该绑定的Looper对象
        mThread = Thread.currentThread();
    }

	
    /**
     *初始化主线程的Looper对象,由android系统调用,不需要我们自己调用
     */
    public static void prepareMainLooper() {
    	//初始化Looper,主线程创建的Looper是不需要结束loop的,如果手动调用结束方法会抛出异常
        prepare(false);
       
        //主线程的Looper只能由android系统初始化,我们自己初始化会抛异常
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
             //记录主线程的Looper
            sMainLooper = myLooper();
        }
    }

    /** 获取主线程的Looper
     */
    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }

 /**
     * 返回与当前线程相关Looper对象,如果返回null,则说明当前线程没有关联Looper
     */
    public static Looper myLooper() {
        return sThreadLocal.get();
    }

  
    /**
     * 返回当前线程绑定的Looper对象内的MessageQueue ,这个必须在Looper中运行的线程中调用,否则会报空指针异常
     */
    public static MessageQueue myQueue() {
        return myLooper().mQueue;
    }
	

    /**
     * 轮询MessageQueue中的Message,如果是子线则需要手动调用loop方法轮询处理消息
     */
    public static void loop() {
    	//1.获取当前线程绑定的looper对象
        final Looper me = myLooper();
        if (me == null) {
        //在子线程中创建Handler,如果没有调用Looper.prepare(),那么myLooper()方法是获取不到Looper对象的.则会抛异常,
        //而主线程由于系统已经调用了prepareMainLooper方法,因此没有这个问题
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        //2.获取Looper的消息队列
        final MessageQueue queue = me.mQueue;

        // ...

        for (;;) {
       		 //3.这里是死循环,从MessageQueue中遍历所有的Message对象
            Message msg = queue.next(); // might block (next方法是阻塞的方法)
			
			//消息为null,结束loop
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

           // ...
           
           /* 4.获取Message所关联的target,这里的target其实就是Handler对象,后面会解释
           调用关联的Handler对象的dispatchMessage方法,将消息传递给Handler去处理*/
            msg.target.dispatchMessage(msg);

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // ...

			// 释放消息,清空Message中保存的各种引用
            msg.recycle();
        }
    }

   
    
    /**
     * 判断当前Looper内的线程是否就是当前线程
     */
    public boolean isCurrentThread() {
        return Thread.currentThread() == mThread;
    }

    /**
     * 非安全的退出Looper,会导致loop方法终止,退出时并不保证消息队列中的所有message都已处理完毕
     */
    public void quit() {
        mQueue.quit(false);
    }

    /**
	* 安全的结束Looper,loop方法仅当消息队列中的所有message都处理完毕后才终止,但是不包括延时处理的message
     */
    public void quitSafely() {
        mQueue.quit(true);
    }

    

    /**
     * 获取与之Looper关联的线程对象
     */
    public Thread getThread() {
        return mThread;
    }

  ...

通过分析Looper的源码,我们可以了解到Looper类是用来轮询当前线程相关联的Message对象的,每轮询一个message,就会通过该message持有的Handler的引用也就是target去处理消息,具体是通过dispatchMessage方法分发处理消息,稍后会讲到.

默认创建的线程是没有与任何Looper进行关联的,必须要先通过Looper的prepare()静态方法来创建并通过ThreadLocal进行关联绑定,接着轮询处理消息的时候必须要手动调用loop方法进行处理.


子线程创建Handler

下面是一个经典的子线程中创建Handelr,并通过Looper轮询和处理消息的例子:

class LooperThread extends Thread {
    public Handler mHandler;
    public void run() {
    	//初始化Looper
        Looper.prepare();
        //创建处理消息的Handler,最开始已经分析过子线程中创建Handler,必须要先有Looper
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };
        //开始轮询
        Looper.loop();
    }
}

在主线程中创建Handler的,系统已经帮我们完成了Looper.prepare();和 Looper.loop();的工作了,因此我们可以直接使用Handler.


疑问

分析Looper源码的时候有以下2个疑问待解决,定位到loop方法中的msg.target.dispatchMessage(msg);

1.target是何时与Message进行关联的呢?
2.dispatchMessage是如何处理轮询出来的消息(message对象)?

target的由来

target是Message对象的一个属性,要知道它是啥时候赋值的,那么我们可以先Message的创建说起,Message有多中方式创建,通过空参的构造方法创建,或者通过其多个静态的obtain方法创建.
空参的构造方法内一行代码也没有,看不到有啥有用的线索,obtain方法倒是有几个可以直接看出对target的赋值声明,例如:

...
public static Message obtain(Handler h) {
    Message m = obtain();
    m.target = h;

    return m;
}


public static Message obtain(Handler h, Runnable callback) {
    Message m = obtain();
    m.target = h;
    m.callback = callback;

    return m;
}

...

但是这些静态方法并不是创建Message的唯一途径,因此都不能保证target就已经关联了Handler对象,那么我们只能从Handler的sendMessage方法入手了.

public final boolean sendMessage(Message msg) {
	//继续往下调用sendMessageDelayed方法,该方法是一个延时发送消息的方法,这里传递0表示马上发送.
	return sendMessageDelayed(msg, 0);
}

接着sendMessageDelayed方法

public final boolean sendMessageDelayed(Message msg, long delayMillis) {
	if (delayMillis < 0) {
	 	delayMillis = 0;
	}
	//继续往下调用sendMessageAtTime,功能是一样的,名字不同而已.
	return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

}

接着sendMessageAtTime方法

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
	//判断此时的Looper的MessageQueue是否为null,是者打印警告log
	MessageQueue queue = mQueue;
	if (queue == null) {
	    RuntimeException e = new RuntimeException(
	            this + " sendMessageAtTime() called with no mQueue");
	    Log.w("Looper", e.getMessage(), e);
	    return false;
	}
	//继续往下调用enqueueMessage
	return enqueueMessage(queue, msg, uptimeMillis);
}

接着enqueueMessage方法

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
	/*ok,终于找到看到真相了.this就是当前创建的Handler,也就是说我们通过Handler的sendMessage发送Message的时候,
	该Message对象将该Handler保存到它的target变量中.*/
	msg.target = this;
	if (mAsynchronous) {
	    msg.setAsynchronous(true);
	}
	//这一步是将消息存放到消息队列中
	return queue.enqueueMessage(msg, uptimeMillis);
}

Handler#dispatchMessage的处理

dispatchMessage是Handler的方法,就是用来分发处理消息的,直接看源码


    /**
     * 分发消息
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
        	//交由Message处理,通过Handler的post方法发送的消息Runnable会赋值给msg的callback属性
            handleCallback(msg);
        } else {
        	//交由handler的Callback处理
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                	//如果Callback的handleMessage方法返回true,那么dispatchMessage方法将结束,意味着下面的Handler的handleMessage方法将不被回调.
                    return;
                }
            }
	      /*如果mCallback==null,或者Callback的handleMessage方法返回false的话,Handler的
	      handleMessage才可以接受到消息.通过Handler的无参构造方法创建Handler的话mCallback就是等于null的.
	      因此我们重写Handler的handleMessage方法就可以接收到我们发送的Message对象*/
	       handleMessage(msg);
        }
    }
 	//回调给我们处理自己的消息
 	public void handleMessage(Message msg) {
    }
 	
 	//直接处理Message内的Runnable中的run方法
	private static void handleCallback(Message message) {
	    message.callback.run();
	}

分析Handler的事件分发机制可知,当Handler收到消息开分发的时候优先会判断Message中是否有绑定Runnable对象,如果有的话,直接执行run方法的逻辑,否则继续判断Handler中是否有绑定Callback对象,如果有则执行Callback的handleMessage方法,并判断其返回值,如果返回true则分发结束,返回false,则会执行我们重写Handler的handleMessage方法.


总结

通过上面的Handler,Looper,Message的源码分析,大概的结论是:
1.Handler通过发送和处理Message
2. Looper通过轮询MessageQueue无限循环轮询Message,同时将Message回传给对应的Handler处理
3. 创建Handler必须要调用Looper.prepare()方法去初始化Looper,否则将报异常,主线程的Looper是由android系统去调用Looper.prepare()的;
4. Looper的loop()方法将是开启消息轮询的关键方法,非UI线程必须


扩展

Handler#post方法分析

post方法会将Runnable对象添加到message queue中,Runnable中的run方法最终是在什么线程中执行是要看创建该Handler所在的线程,如果是在主线程中创建的Handler,那么该run方法就会在主线程中执行,否则是在子线程中执行.
返回值表示该Runnable是否成功的添加到了消息队列中

public final boolean post(Runnable r) {
    return sendMessageDelayed(getPostMessage(r), 0);
}

getPostMessage做了什么操作呢?
很简单,就是创建一个Message,然后将Runnable对象赋值给它的callback 属性.

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

接着就和Handler#sendMessage方法一样了.将消息发送到Looper中的MessageQueue中.具体是通过上面提到的enqueueMessage方法.

主线程的Looper在哪里创建

Activity的启动一般会调用到ActivityThread,里面有main方法,是初始化activity必经阶段,主线程的Looper创建和调用轮询都是在ActivityThread的main方法中执行的

public static void main(String[] args) {
    SamplingProfilerIntegration.start();
    // CloseGuard defaults to true and can be quite spammy.  We
    // disable it here, but selectively enable it later (via
    // StrictMode) on debug builds, but using DropBox, not logs.
    CloseGuard.setEnabled(false);
    Environment.initForCurrentUser();
    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());
    Security.addProvider(new AndroidKeyStoreProvider());
    Process.setArgV0("<pre-initialized>");
    
    //1.创建主线程的Looper
    Looper.prepareMainLooper();
   
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
	
	//2.创建主线程的Handler
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    AsyncTask.init();
    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }
	
	//3.开启轮询
    Looper.loop();
    
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

主线程中的Looper.loop()一直无限循环为什么不会造成ANR?

分析Looper的loop源码的时候可以知道MessageQueue是通过next()方法去获取Message的,而next()方法又是一个阻塞的方法,所以主线程是阻塞的,因此CPU并不会消耗太多资源在主线程中,像我们平时自己new 的线程一样,如果run方法里面没有阻塞的语句,那么很快就得结束回收掉了.

既然主线程阻塞了,那么为什么还能调用各种生命周期呢?
调用生命周期是因为有Looper,有MessageQueue,还有沟通的桥梁Handler,通过IPC机制调用Handler发送各种消息,保存到MessageQueue中,然后在主线程中的Looper提取了消息,并在主线程中调用Handler的方法去处理消息.最终完成各种生命周期方法的调用.

下面贴出主线程的Handler的handleMessage方法的处理代码:

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");
            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 != 0, msg.arg2);
            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 != 0, msg.arg2);
            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;
        case DESTROY_ACTIVITY:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
            handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
                    msg.arg2, false);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case BIND_APPLICATION:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case EXIT_APPLICATION:
            if (mInitialApplication != null) {
                mInitialApplication.onTerminate();
            }
            Looper.myLooper().quit();
            break;
        case NEW_INTENT:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
            handleNewIntent((NewIntentData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case RECEIVER:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
            handleReceiver((ReceiverData)msg.obj);
            maybeSnapshot();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case CREATE_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
            handleCreateService((CreateServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case BIND_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
            handleBindService((BindServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case UNBIND_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
            handleUnbindService((BindServiceData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case SERVICE_ARGS:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
            handleServiceArgs((ServiceArgsData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case STOP_SERVICE:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
            handleStopService((IBinder)msg.obj);
            maybeSnapshot();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case REQUEST_THUMBNAIL:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
            handleRequestThumbnail((IBinder)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case CONFIGURATION_CHANGED:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
            mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
            handleConfigurationChanged((Configuration)msg.obj, null);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case CLEAN_UP_CONTEXT:
            ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
            cci.context.performFinalCleanup(cci.who, cci.what);
            break;
        case GC_WHEN_IDLE:
            scheduleGcIdler();
            break;
        case DUMP_SERVICE:
            handleDumpService((DumpComponentInfo)msg.obj);
            break;
        case LOW_MEMORY:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
            handleLowMemory();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case ACTIVITY_CONFIGURATION_CHANGED:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
            handleActivityConfigurationChanged((IBinder)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case PROFILER_CONTROL:
            handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
            break;
        case CREATE_BACKUP_AGENT:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
            handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case DESTROY_BACKUP_AGENT:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
            handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case SUICIDE:
            Process.killProcess(Process.myPid());
            break;
        case REMOVE_PROVIDER:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
            completeRemoveProvider((ProviderRefCount)msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case ENABLE_JIT:
            ensureJitEnabled();
            break;
        case DISPATCH_PACKAGE_BROADCAST:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
            handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case SCHEDULE_CRASH:
            throw new RemoteServiceException((String)msg.obj);
        case DUMP_HEAP:
            handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
            break;
        case DUMP_ACTIVITY:
            handleDumpActivity((DumpComponentInfo)msg.obj);
            break;
        case DUMP_PROVIDER:
            handleDumpProvider((DumpComponentInfo)msg.obj);
            break;
        case SLEEPING:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
            handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case SET_CORE_SETTINGS:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
            handleSetCoreSettings((Bundle) msg.obj);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case UPDATE_PACKAGE_COMPATIBILITY_INFO:
            handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
            break;
        case TRIM_MEMORY:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
            handleTrimMemory(msg.arg1);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
        case UNSTABLE_PROVIDER_DIED:
            handleUnstableProviderDied((IBinder)msg.obj, false);
            break;
        case REQUEST_ASSIST_CONTEXT_EXTRAS:
            handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
            break;
        case TRANSLUCENT_CONVERSION_COMPLETE:
            handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
            break;
        case INSTALL_PROVIDER:
            handleInstallProvider((ProviderInfo) msg.obj);
            break;
    }
    if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}

猜你喜欢

转载自blog.csdn.net/mChenys/article/details/85261896