Android 开机动画流程

参考链接:http://www.mamicode.com/info-detail-399016.html

Android 开机动画流程_第1张图片


1.启动surfaceflinger

service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote
// 根据UTC信息,可大致计算启动surfaceflinger的时间是:2016-06-05 21:14:15.231112
<13>[    4.500719] (0)[1:init]init: starting 'surfaceflinger'
<7>[    4.500893] (0)[1:init][1:init] fork [206:init]
<14>[    4.500993] (0)[1:init]init: PropSet [init.svc.surfaceflinger:running] Start>>
<14>[    4.501033] (0)[1:init]init: PropSet [init.svc.surfaceflinger:running] Done
<4>[   20.774432][thread:129][RT:20764482924] 2016-06-05 13:14:31.504825 UTC; android time 2016-06-05 21:14:31.504825

2.surfaceflinger启动bootanimation

在它的init方法中通过ctl.start的方式启动bootanim。

void SurfaceFlinger::startBootAnim() {
    // start boot animation
    property_set("service.bootanim.exit", "0");
    property_set("ctl.start", "bootanim");
}
log信息:

// SurfaceFlinger started

06-05 13:14:15.917427   206   206 I SurfaceFlinger: SurfaceFlinger is starting
06-05 13:14:15.917584   206   206 I SurfaceFlinger: SurfaceFlinger's main thread ready to run. Initializing graphics H/W...
// init start bootanimation
<14>[    5.865806] (2)[1:init]init: [PropSet]: pid:206 uid:1000 gid:1003 set service.bootanim.exit=0
<14>[    5.865817] (2)[1:init]init: PropSet [service.bootanim.exit:0] Start>>
<14>[    5.865895] (2)[1:init]init: PropSet [service.bootanim.exit:0] Done
<14>[    5.866460] (2)[1:init]init: [PropSet]: pid:206 uid:1000 gid:1003 ctl.start bootanim
<14>[    5.866605] (2)[1:init]init: computing context for service '/system/bin/bootanimation'
<13>[    5.866724] (2)[1:init]init: starting 'bootanim'
<7>[    5.866838] (2)[1:init][1:init] fork [619:init]
<14>[    5.866903] (2)[1:init]init: PropSet [init.svc.bootanim:running] Start>>
<14>[    5.866982] (2)[1:init]init: PropSet [init.svc.bootanim:running] Done
// bootanimation started
06-05 13:14:16.605907   206   206 I SurfaceFlinger: [void android::SurfaceFlinger::checkEnableBootAnim()] boot reason = '0'
06-05 13:14:16.607570   206   206 I boot    : BOOTPROF:BootAnimation:Start:5842
06-05 13:14:16.723475   619   619 D BootAnimation: [BootAnimation frameworks/base/cmds/bootanimation/bootanimation_main.cpp main 41]start Jan 19 2015 12:00:29

3. bootanimation何时退出

bootanimation进入循环播放动画过程,但每次循环都会去检查是否需要退出。

也就是退出的方式是service.bootanim.exit这个系统属性被set为非0

#define EXIT_PROP_NAME "service.bootanim.exit"
void BootAnimation::checkExit() {
    // Allow surface flinger to gracefully request shutdown
    char value[PROPERTY_VALUE_MAX];
    property_get(EXIT_PROP_NAME, value, "0");
    int exitnow = atoi(value);
    if (exitnow) {
        requestExit();
    }
}

// Threads.cpp
void Thread::requestExit()
{
    Mutex::Autolock _l(mLock);
    mExitPending = true;
}
bool Thread::exitPending() const
{
    Mutex::Autolock _l(mLock);
    return mExitPending;
}
log信息:

// 从pid为206可以看到,还是surfaceflinger来关闭bootanim的
// 2016-06-05 21:14:33.204018
<14>[   22.473645] (0)[1:init]init: [PropSet]: pid:206 uid:1000 gid:1003 set service.bootanim.exit=1
<14>[   22.473663] (0)[1:init]init: PropSet [service.bootanim.exit:1] Start>>
<14>[   22.473756] (0)[1:init]init: PropSet [service.bootanim.exit:1] Done
<4>[   22.474564] (2)[433:Binder_2]BOOTPROF:     22474.555539:BOOT_Animation:END
<4>[   20.804432][thread:130][RT:20794464385] 2016-06-05 13:14:31.534805 UTC; android time 2016-06-05 21:14:31.534805

4.谁触发surfaceflinger关闭bootanim?

是WMS通过IPC调用surfaceflinger的bootFinished()方法关闭bootanim。

//WindowManagerService.java
public void performEnableScreen() {
	... ...
	IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
	if (surfaceFlinger != null) {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken("android.ui.ISurfaceComposer");
		surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
		        data, null, 0);
		data.recycle();
	}
	mActivityManager.bootAnimationComplete();
	... ...
}

//06-05 21:14:33.213177   206   433 I SurfaceFlinger: Boot is finished (17295 ms)	
void SurfaceFlinger::bootFinished()
{
    const nsecs_t now = systemTime();
    const nsecs_t duration = now - mBootTime;
    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );

    property_set("service.bootanim.exit", "1");
}

5.谁触发WMS关闭bootanim?
ActivityThread.java中的Idler的queueIdle()被调用时,会触发。一般地,这个ActivityThread的实例是Launcher的。

// ActivityThread.java
private class Idler implements MessageQueue.IdleHandler {
    public final boolean queueIdle() {
        IActivityManager am = ActivityManagerNative.getDefault();
        am.activityIdle(a.token, a.createdConfig, stopProfiling);
    }
}
mStackSupervisor.activityIdleInternalLocked(token, false, config);
mService.postFinishBooting(booting, enableScreen);
enableScreenAfterBoot()
mWindowManager.enableScreenAfterBoot();
performEnableScreen();

6.最关键是何时Idler的queueIdle()会被调用

// ActivityThread.java
handleResumeActivity
Looper.myQueue().addIdleHandler(new Idler());
// MessageQueue.java
next()
// If first time idle, then get the number of idlers to run.
// Idle handles only run if the queue is empty or if the first message
// in the queue (possibly a barrier) is due to be handled in the future.

关于此部分,不懂。


你可能感兴趣的:(Android 开机动画流程)