Android bootanim开机动画启动流程

1. system进程在启动过程中会调用SurfaceFlinger类的静态成员函数instantiate来启动SurfaceFlinger服务。启动过程中,首先创建一个SurfaceFlinger实例,此实例会被一个SP 指针引用。当一个对象被一个智能指针第一次引用的时候,该类的onFirstRef方法将被调用:

void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);
}

2. SurfaceFlinger类继承自Thread类,因此当它的run方法被调用的时候,系统就会创建一个新的线程。这个线程在第一次运行之前,会调用该类的readToRun方法。并且调用mReadyToRunBarrier的wait让主线程(init进程)处于等待状态。readyToRun方法会进行主屏幕以及openGL库的初始化,完成后会调用mReadyToRunBarrier的open来唤醒主线程。紧接着开始启动动画:

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

3. 当系统属性发生改变时,init进程就会收到一个系统属性变化的通知,这个通知最终由在init进程中的函数handle_property_set_fd来处理。由于此系统属性是以ctrl.开头的控制类型的属性,因此当属性变更时会启动一个名字为“bootanim”的服务。通过这个名字,可以找到对应的应用程序为/system/bin/bootanimation。于是应用程序的入口函数main函数将被调用:

int main()
{
    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sf.nobootanimation", value, "0");
    int noBootAnimation = atoi(value);
    ALOGI_IF(noBootAnimation,  "boot animation disabled");
    if (!noBootAnimation) {

        sp<ProcessState> proc(ProcessState::self());
        ProcessState::self()->startThreadPool();

        // create the boot animation object
        sp<BootAnimation> boot = new BootAnimation();

        IPCThreadState::self()->joinThreadPool();

    }
    return 0;
}

4. 由于BootAnimation对象在显示动画时需要与SurfaceFlinger服务通信,因此,应用程序bootanimation就需要启动一个binder线程池。当一个BootAnimation对象第一个被一个只能智能指针引用的时候,BootAnimation的onFirstRef方法将被调用:

void BootAnimation::onFirstRef() {
    status_t err = mSession->linkToComposerDeath(this);
    ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
    if (err == NO_ERROR) {
        run("BootAnimation", PRIORITY_DISPLAY);
    }
}

在init.rc中声明的服务此时将被启动

service bootanim /system/bin/bootanimation
    class core
    user graphics
    group graphics audio
    disabled
    oneshot

5. BootAnimation类继承自Thread类,当它的run方法被调用时,将会调用该类的readToRun方法。在/data/local/bootanimation.zip、/system/media/bootanimation.zip、/system/media/bootanimation-encrypted.zip(加密动画)查找是否存在相应的动画压缩包,若存在则使用用户自定义的动画,否则使用android默认的开机动画

status_t BootAnimation::readyToRun() {
    mAssets.addDefaultAssets();

.......
.......
.......

    if (encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
        mZipFileName = SYSTEM_ENCRYPTED_BOOTANIMATION_FILE;
    }
    else if (access(OEM_BOOTANIMATION_FILE, R_OK) == 0) {
        mZipFileName = OEM_BOOTANIMATION_FILE;
    }
    else if (access(USER_BOOTANIMATION_FILE, R_OK) == 0) {
        mZipFileName = USER_BOOTANIMATION_FILE;
    }
    else if (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) {
        mZipFileName = SYSTEM_BOOTANIMATION_FILE;
    }
    return NO_ERROR;
}

6. 当线程准备好运行时,其threadLoop方法会被调用,完整动画zip的解析显示。

 

7. 停止动画。当系统启动完成时,会调用SurfaceFlinger中的bootFinished方法,通过设定系统参数的方式结束动画的播放

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

 

转载于:https://my.oschina.net/u/3750358/blog/1590345

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值