Android 8.1 开机启动流程的收尾_bootanimation开机动画结束和BOOT_COMPLETE广播发送流程整理

一开始还是以为是Launcher起来后线程空闲回调Ams的接口开始进行关闭开机动画,但实际上看了下不仅仅是这个条件。不过还是从这里开始结合日志一起看。

在ActivityThread::handleLaunchActivity的过程中,会在resume阶段handleResumeActivity方法里面在加载完window之后将自己实现的Idlehandler添加到自己的消息队列里面,当Looper发现消息队列空闲的时候就会回调queueIdle方法

                r.nextIdle = mNewActivities;
                mNewActivities = r;
                if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
                Looper.myQueue().addIdleHandler(new Idler());

Idler实现的MessageQueue.IdleHandler接口就一个queueIdle方法,里面关键的就是会回调ams的activityIdle。

private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            boolean stopProfiling = false;
            if (mBoundApplication != null && mProfiler.profileFd != null
                    && mProfiler.autoStopProfiler) {
                stopProfiling = true;
            }
            if (a != null) {
                mNewActivities = null;
                IActivityManager am = ActivityManager.getService();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            if (stopProfiling) {
                mProfiler.stopProfiling();
            }
            ensureJitEnabled();
            return false;
        }
    }

Ams

    @Override
    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                ActivityRecord r =
                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
                                false /* processPausingActivities */, config);
                if (stopProfiling) {
                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
                        clearProfilerLocked();
                    }
                }
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

ActivityStackSuperVisor的activityIdleInternalLocked方法,会报告启动时间结束,还有就是检查是否是还在开机阶段然后结束开机流程。意思就是桌面都已经拿到焦点显示好了,开机动画可以退役了。在这里会修改Ams的mBooting全局变量为true,然后enableScreen也是true,发送Message给Ams进行处理,也就是开篇提到的。

            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
            if (isFocusedStack(r.getStack()) || fromTimeout) {
                booting = checkFinishBootingLocked();
            }
    /**
     * Called when the frontmost task is idle.
     * @return the state of mService.mBooting before this was called.
     */
    private boolean checkFinishBootingLocked() {
        final boolean booting = mService.mBooting;
        boolean enableScreen = false;
        mService.mBooting = false;
        if (!mService.mBooted) {
            mService.mBooted = true;
            enableScreen = true;
        }
        if (booting || enableScreen) {
            mService.postFinishBooting(booting, enableScreen);
        }
        return booting;
    }
    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
        Exception e = new Exception("xian postFinishBooting");
        e.printStackTrace();
        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
    }

这是对应的log打印的栈

07-03 10:20:26.632  3015  3027 W System.err: java.lang.Exception: xian postFinishBooting
07-03 10:20:26.633  3015  3027 W System.err: 	at com.android.server.am.ActivityManagerService.postFinishBooting(ActivityManagerService.java:7244)
07-03 10:20:26.633  3015  3027 W System.err: 	at com.android.server.am.ActivityStackSupervisor.checkFinishBootingLocked(ActivityStackSupervisor.java:1874)
07-03 10:20:26.633  3015  3027 W System.err: 	at com.android.server.am.ActivityStackSupervisor.activityIdleInternalLocked(ActivityStackSupervisor.java:1916)
07-03 10:20:26.633  3015  3027 W System.err: 	at com.android.server.am.ActivityManagerService.activityIdle(ActivityManagerService.java:7231)
07-03 10:20:26.633  3015  3027 W System.err: 	at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:309)
07-03 10:20:26.633  3015  3027 W System.err: 	at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2919)
07-03 10:20:26.633  3015  3027 W System.err: 	at android.os.Binder.execTransact(Binder.java:697)
处理Message是要干两件事,一件是finishBooting,一件是enableScreenAfterBoot。
            case FINISH_BOOTING_MSG: {
                if (msg.arg1 != 0) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
                    finishBooting();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
                if (msg.arg2 != 0) {
                    enableScreenAfterBoot();
                }
                break;
            }
在finishBooting里面,
  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值