安卓4.2可用方法2-4,第一種方法未驗證。
從理論上來說,android 有4個開機啟動畫面。
第一個應該是U-BOOT的啟動畫面,有些設備為了滿足按動電源即有顯示,在UBOOT里加了開機畫面,實現的方式當然只能是寫物理地址,也因此隨廠家不同具體的實現千差萬別。加上我們接觸的手機平板等設備大多沒這個開機畫面,所以這里就不贅述了。
第二個啟動畫面實際是LINUX的啟動畫面,但這個啟動畫面在ANDROID里默認是關閉的,需要打開時就打開kernel選項:
CONFIG_FRAMEBUFFER_CONSOLE
CONFIG_LOGO
意即KERNEL支持幀緩沖控制台,並且顯示開機LOGO。
最方便的辦法當然是make menuconfig。
第一個對應的配置菜單項為:Device Drivers ---> Graphics support ---> Console display driver support ---> Framebuffer Console support。
第二個對應的配置菜單項為:Device Drivers ---> Graphics support ---> Bootup logo。
具體執行第一個動畫的文件在 kernel/drivers/video/fbmem.c
里面有fb_prepare_logo函數,負責LOAD 開機畫面。這個函數會調用kernel/drivers/video/logo/logo.c的fb_find_logo函數來確認最終會用哪張圖片。
開機的圖片也都在kernel/drivers/video/logo/ 目錄下,要注意這些圖片不是標准的PNG等格式,網上提供了工具來進行轉換為所需的PPM格式,這里就不贅述了。
第三個開機畫面已經進入了android的范圍,是在INIT進程啟動的時候加載的。
具體來說,是在system/core/init/init.c 里干的。
queue_builtin_action(console_init_action, "console_init");
console_init_action函數中有一行:
load_565rle_image(INIT_IMAGE_FILE)
這個函數簡單說就是顯示了一張圖,圖的路徑在INIT_IMAGE_FILE。
INIT_IMAGE_FILE的定義是在system/core/init/init.h:
#define INIT_IMAGE_FILE "/initlogo.rle"
這個rle文件一般放在device目錄下,可以自己用命令搜尋。網上也有工具提供各種圖片對這個RLE格式的轉換。
第四個開機畫面,是我們最常見的安卓手機開機畫面。從實現方式來說,其實就是在init.rc里添加了一個bootAnimation的服務,這個服務不是自動運行的,它有一定的運行條件,具體可以參看下它的定義:
service bootanim /system/bin/bootanimation
class main
user graphics
group graphics
disabled
oneshot
service shutdownanim /system/bin/bootanimation -shutdown
class main
user graphics
group graphics
disabled
oneshot
什么時候它會被執行呢?簡單說,就是surfaceFlinger啟動的時候,會改變系統變量讓它起來,而系統完成啟動后(launcher已經起來了),activityManagerService會輾轉通知surfaceFlinger,然后又用改變系統屬性的辦法關閉bootanimation進程。
如上所述,我們就理解了bootanimation是一個循環執行的進程。它的代碼在:
frameworks/base/cmds/bootanimation/BootAnimation.cpp
從代碼可知這次開機動畫有2種模式,一種是使用兩張圖片利用某種效果來造成動態,另一種則是用一個圖包循環顯示的方式來形成動態。當然,這時因為mediaplayer已經起來,播放開機動畫的時候可以同時播放開機音樂。第一種雙圖片模式稱為android模式,第二種圖包模式稱為movie模式,他們在循環時通過條件變量來選擇其一:
if (mAndroidAnimation) {
r = android();
} else {
r = movie();
}
這兩種模式具體的實現動畫的代碼比較簡單,就不討論了,只看定義需要的文件之處:
第一種android模式:
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
這兩張圖片都在frameworks/base/core/res/assets/images目錄下,替換即可。
第二種movie模式:
mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)
mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR)
#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
#define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
找到並替換bootanimation.zip即可。