Android App运行核心,Handler,Looper,Message

463 阅读3分钟

App进程是由于Zygote进程孵化来的,首先创建Looper,Looper.prepareLooper(),然后调用ActivityThread.java中的main函数创建ActivityThread对象,调用attach函数,进行初始化。通过ActivityManager.java的getService函数获取ActivityManagerService,通过它的attachApplication函数进行初始化,然后调用attachApplicationLocked函数继续执行。 接着就在main函数中进入Looper.loop()函数中进行消息循环。

Looper.java中 looper函数是app运行的核心

public static void loop() {

查找之前创建的Looper

final Looper me = myLooper();

所有的工作都是围绕着Looper进行的,如果Looper是空的话,应用就不能运行,它是循环的核心。

final MessageQueue queue = me.mQueue;

循环中的消息队列是Looper的成员

for (;;) {
    Message msg = queue.next(); // might block
    if (msg == null) {
        // No message indicates that the message queue is quitting.
        return;
    }

进入死循环,取出要执行的消息,所有要处理的消息最后都要发到这个消息队列里,然后再一一取出。 需要说明的是,如果没有消息的话,就会阻塞在这里,因为是linux底层的阻塞,cpu就会休眠,这个不会影响主线程的执行。一旦有消息送过来,立马激活,进行消息处理。

if (observer != null) {
    token = observer.messageDispatchStarting();
}
long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid);
try {
    msg.target.dispatchMessage(msg);
    if (observer != null) {
        observer.messageDispatched(token, msg);
    }
    dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} catch (Exception exception) {
    if (observer != null) {
        observer.dispatchingThrewException(token, msg, exception);
    }
    throw exception;
} finally {
    ThreadLocalWorkSource.restore(origWorkSource);
    if (traceTag != 0) {
        Trace.traceEnd(traceTag);
    }
}

上述就是消息处理,如果在执行的过程中,没有catch的异常,就会抛出异常,然后应用就会挂掉。

如果不想应用挂掉的话,最好在Application中添加Handler的处理

Handler(Looper.getMainLooper()).post {
    while (true) {
        try {
            Looper.loop()
        } catch (e: Throwable) {

        }
    }
}

这样就会再次走入一个单独的Looper.loop,它们是一个Looper,因为这个死循环,应用就不会强制关闭 不过这个时候,应用的状态不正常了,可以做个几次判断,加上日志保存,如果还不行,程序出现错误,就应该退出程序。

下面说说Handler,所有的消息派送都用到它。

msg.target.dispatchMessage(msg);

消息中的target就是一个Handler,dispatchMessage函数是统一处理消息的入口。

public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

可以把callback封装在Messsge中,主线程中创建Handler的时候,把主线的队列赋值给它, 通过以下函数发送消息到消息队列。

public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
public final boolean post(@NonNull Runnable r) {
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
public final boolean sendEmptyMessage(int what)
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
public final boolean sendMessage(@NonNull Message msg) {
public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {

也可以通过在子线程创建自己的Handler,联合使用HandlerThread

HandlerThread handlerThread = new HandlerThread("work");
handlerThread.run();

Hanlder hanlder = new Hanlder(handlerThread.getLooper());

也可以覆写Handler,实现子类

private static class InnerHandler extends Handler {
    public InnerHandler(@NonNull Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(@NonNull Message msg) {
    }
}

也可以这么写

Handler handler = new InnerHandler(Looper.getMainLooper(), new Handler.Callback() {
    @Override
    public boolean handleMessage(@NonNull Message msg) {
        return false;
    }
});

这里是一个Callback回调,如果这里返回false,就可以处理两个handleMessage消息,根据实际情况去编写代码。

Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
        new AsyncTaskResult<Result>(this, result));
message.sendToTarget();

通过上述的Handler发送给自己去处理。