BootAnimation簡析

luoliang_13發表於2024-06-16

BootAnimation簡析

BootAnimation是開機動畫,其對應原始碼在frameworks\base\cmds\bootanimation(這裡使用android12的程式碼檢視,不同版本程式碼有差異,但大體邏輯一般都差別不大),其編譯產物是個二進位制可執行檔案bootanimation,在開機過程中會執行播放開機動畫,其目錄中有個FORMAT.md檔案有配置開機動畫的簡單介紹,BootAnimation程式碼中主要是解析開機動畫資源包進行播放,然後在系統準備好後結束開機動畫

BootAnimation入口是其main方法,在bootanimation_main.cpp中

BootAnimation簡析
這裡可以看到其main方法中主要是建立了個BootAnimation的物件,並呼叫其run方法

首先檢視下BootAnimation.h檔案,可知BootAnimation繼承了Thread和DeathRecipient(DeathRecipient繼承了RefBase)

BootAnimation簡析

因為其繼承的Thread和DeathRecipient

其重寫了幾個關鍵方法,其在建立其物件並呼叫run方法後會分別回撥到

onFirstRef:繼承自RefBase,其在建立物件和指標的時候會呼叫

readyToRun:繼承自Thread,其線上程執行後會先呼叫

threadLoop:繼承自Thread,其線上程執行時會呼叫

binderDied:繼承自DeathRecipient,一般當binder異常結束時會呼叫

根據其main方法中程式碼,BootAnimation的onFirstRef、readyToRun、threadLoop方法會相繼執行,這裡簡要分析這三個方法中的邏輯

onFirstRef

BootAnimation簡析

這裡mSession是SurfaceComposerClient的物件,linkToComposerDeath是監聽顯示對端surfaceflinger異常退出,這裡不細看

preloadAnimation主要是載入動畫資源,做開機動畫的準備動作

BootAnimation簡析

findBootAnimationFile

BootAnimation簡析

這裡可以看到有好幾個分支,而其程式碼都是相似的,分別對應不同場景生成一個字串列表,放入對應的字串,然後呼叫findBootAnimationFileInternal方法,如下可看到,這裡的字串都是一些開機動畫的資源壓縮檔案

BootAnimation簡析

這裡根據一些配置項來進行區分判斷,然後檢視下findBootAnimationFileInternal方法:

BootAnimation簡析

在findBootAnimationFileInternal方法中會對傳入的字串列表進行遍歷,如果字串對應的檔案存在且可訪問,則會將其賦值給mZipFileName然後返回

所以從上述分析看findBootAnimationFile就是根據配置和預置的一些路徑來查詢動畫資源,然後賦值給mZipFileName

loadAnimation

BootAnimation簡析

檢視loadAnimation方法,這裡建立了一個Animation物件,然後將之前找到的資原始檔等資訊新增到物件中,然後主要呼叫了parseAnimationDesc方法和preloadZip方法來解析資源包中的檔案

BootAnimation簡析

parseAnimationDesc是解析資源包中的desc.txt檔案,該檔案中配置了播放動畫的資源、大小等資訊,可結合原始碼中FORMAT.md介紹和程式碼一起看,這裡不細講

BootAnimation簡析

preloadZip是結合解析的desc.txt的資訊解析資源包中的其他檔案資訊

readyToRun

BootAnimation簡析

readyToRun的程式碼較多,這裡主要是準備顯示相關,因為bootanimation是c++編寫的,所以沒有一般意義上的Activity、視窗、控制元件等東西,而是直接透過顯示相關介面呼叫到surfaceflinger建立對應圖層,然後使用opengl介面進行繪製,這裡也會做一些繪製相關的準備工作

threadLoop

BootAnimation簡析

可以看到threadLoop方法分兩部分,一部分是具體的繪製等相關邏輯,其根據前面是否有找到資源包分別呼叫android和movie方法,然後則是結束繪製的相關邏輯

android和movie主要差異在於繪製的內容,其他邏輯相似,android因其資源問題肯定要簡單一些,這裡只看下android方法的邏輯

BootAnimation簡析

BootAnimation簡析

從上面程式碼可以看到,這裡主要載入了兩個圖片檔案,然後呼叫opengl介面進行繪製,這裡不具體分析繪製邏輯

上面程式碼中具體繪製部分是在一個do-while迴圈中,這裡檢視下退出迴圈的相關邏輯,其主要在於checkExit和exitPending方法

checkExit

BootAnimation簡析

BootAnimation簡析

如上,checkExit方法會獲取service.bootanim.exit配置項的值,如果為非0,則表示可以退出開機動畫了,這裡會呼叫requestExit方法,該方法是繼承Thread的

BootAnimation簡析

BootAnimation簡析

如上。在呼叫requestExit方法後,exitPending方法即返回true,從而會結束開機動畫

小結

上面主要介紹了BootAnimation的大致結構和流程,並未細緻的每一行程式碼分析,不過了解上面內容後,要具體分析其相關內容時會容易很多,不至於無從下手

相關文章