1. system進程在啓動過程當中會調用SurfaceFlinger類的靜態成員函數instantiate來啓動SurfaceFlinger服務。啓動過程當中,首先建立一個SurfaceFlinger實例,此實例會被一個SP 指針引用。當一個對象被一個智能指針第一次引用的時候,該類的onFirstRef方法將被調用:android
void SurfaceFlinger::onFirstRef() { mEventQueue.init(this); }
2. SurfaceFlinger類繼承自Thread類,所以當它的run方法被調用的時候,系統就會建立一個新的線程。這個線程在第一次運行以前,會調用該類的readToRun方法。而且調用mReadyToRunBarrier的wait讓主線程(init進程)處於等待狀態。readyToRun方法會進行主屏幕以及openGL庫的初始化,完成後會調用mReadyToRunBarrier的open來喚醒主線程。緊接着開始啓動動畫:bash
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方法將被調用:oop
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默認的開機動畫this
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");