android開機動畫製作與播放原理簡介
誰都想擁有一個華麗漂亮的開機動畫,這讓人心情舒暢,android是怎麼來實現的?怎麼製作一個自己的開機動畫?這裡揭開android開機動畫的神秘面紗。
1、製作開關機動畫1.1 開機動畫的位置
system/media/bootanimation.zip,要修改開機動畫就是修改bootanimation這個壓縮檔。如果不存在該壓縮包,使用原生內建的資源,其路徑在system/framework/framework-res.apk/assets/images(android-logo-mask.png,android-logo-shine.png),但是比較難看,比較常見的就是“android”。所以要定製自己的開關機動畫一般都是在system/media/目錄下放置bootanimation.zip和shutanimation.zip.這裡以開機動畫為例,關機動畫和開機動畫其原理一樣。
1.2 bootanimation.zip檔案結構
bootanimation裡面主要包含一個desc.txt以及N個檔案夾。而檔案夾裡面放著的就是開機動畫的圖片資源。decs.txt的作用就是指導系統如何去執行開機動畫。
desc.txt編寫規範,例如開機動畫需要用到2個檔案夾,分別是folder1和folder2,開機的時候,先把folder1裡面的圖片都播放一遍,然後再迴圈播放folder2裡面的檔案,直到進入系統,decs.txt文檔的內容如下:
320 480 12p 1 0 folder1p 0 0 folder2
320 480是代表螢幕的解析度,12表示12幀每秒,簡單地說12代表一秒鐘播放12張圖片;
p 1 0 part1:p就是play。1是播放一次,0是無限次。0代表階段間隔幀數為0。folder1就是說,這條指令是針對folder1這個檔案夾的;
p 0 0 part2:第一個0這裡是代表迴圈播放,第二個0和上面第二條指令一樣。folder2就是第二個檔案夾。
總結規則如下:
第一條指令:[螢幕的解析度] [播放頻率]
第二條指令:[p] [播放次數] [間隔幀數] [檔案夾]
第N條指令: 同上
1.3 壓縮包
把需要用到的folder檔案夾跟decs.txt打包成zip格式,必須是zip,不能是rar,且打包的時壓縮方式選擇“儲存”模式。然後改名成為bootanimation.zip,最後將製作好的zip包push到/system/media目錄下。
注意:bootanimation不能太大,一般最好不要超過3M。
1.4 查看動畫
在終端中輸入命令:
adb shell---> cd /system/bin--->bootanimation 或者bootanimation shut
這樣不用重啟即可查看定製的動畫,方便。
1.5 硬性條件 手機必須有root許可權,否則我們製作好的圖片資源沒辦法push到/system/media目錄,另外執行bootanimaiton也有可能沒有許可權,所以這裡要定製自己的手機必須有root許可權,當然了至於使用什麼樣的方式大家可以根據自己的愛好,各顯神通。 2、播放原理
通過上面的準備開機資源已經製作好了,那android是怎麼來實現播放的。首先對於開關機動畫的播放,android專門使用了一個
native service來實現播放(/system/bin/bootanimation),包括開機鈴聲的實現也是用該service來實現的。
2.1 bootanimation的啟動
Android系統在init.rc中定義了很多Service,具體定義格式可以參考《Android Platform Developer’s Guide》中的“Android Init Language”。Init.rc中定義的Service將會被Init進程建立,其中已經定義的服務就包含bootanimation。
每一項服務必須在/init.rc中定義.Android系統啟動時,init守護進程將解析init.rc和啟動屬性服務,屬性“ ctl.start ”和“ctl.stop ”是用來啟動和停止服務的。一旦收到設定“ ctrl.start ”屬性的請求,屬性服務將使用該屬性值作為服務名找到該服務,啟動該服務。這項服務的啟動結果將會放入“ init.svc.<服務名>“屬性中 。
service bootanim /system/bin/bootanimation user graphics group graphics system audio qcom_oncrpc disabled oneshot
定義了一個bootanim的服務,對應執行/system/bin/bootanimation
disabled 表示init進程建立只是建立它,但不立刻執行;
oneshot 表示該服務只執行一次;
2.2 開機動畫調用
通過上面可知,bootanimation的調用同故宮clt.start 和ctl.stop來實現的,當我們開機啟動時,系統核心起來後,啟動android,這時就會啟動開機動畫具體是在
SurfaceFlinger.cpp的readyToRun方法中調用,為什麼會在這調用,請回顧一下開機流程。
status_t SurfaceFlinger::readyToRun() { // start boot animation service property_set("ctl.start", "bootanim");// }
當android啟動完成後,關閉掉開機動畫
void SurfaceFlinger::bootFinished() { //stop bootanim service property_set("ctl.stop", "bootanim");}
2.3 bootanimation 源碼分析代碼所在位置:/frameworks/base/cmds/bootanimation,其主要包含以下三個檔案
BootAnimation_main.cppBootAnimation.hbootAnimation.cpp
2.3.1 Bootanimation_main.cpp
該檔案是主入口檔案;
int main(int argc, char** argv){#if defined(HAVE_PTHREADS) setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);#endif char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.nobootanimation", value, "0"); int noBootAnimation = atoi(value); LOGI_IF(noBootAnimation, "boot animation disabled"); if (!noBootAnimation) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object bool setBoot = true;bool setRotated = false;bool sePaly = true;if(argc > 1){ if(!strcmp(argv[1],"shut")) setBoot = false;}if(argc > 2){if(!strcmp(argv[2],"nomp3")) sePaly = false;}if(argc > 3){if(!strcmp(argv[3],"rotate")) setRotated = true;}char volume[PROPERTY_VALUE_MAX]; property_get("persist.sys.mute.state", volume, "-1"); int nVolume = -1;nVolume = atoi(volume);if(nVolume == 0 || nVolume == 1 ){sePaly = false;} sp<BootAnimation> boot = new BootAnimation(setBoot,sePaly,setRotated); IPCThreadState::self()->joinThreadPool(); } return 0;}
其主要的功能是根據傳進來的參數決定是是要播放開機還是關機動畫/鈴音,並且啟動BootAnimation;
2.3.2 BootAnimation.cpp
BootAnimation.cpp整合自Thread,在建立時會調用readyToRun()->threadLoop()。
status_tBootAnimation::readyToRun() {……………省略………………………mAndroidAnimation = false; if(bBootOrShutDown){ status_t err = mZip.open("/data/local/bootanimation.zip"); if (err != NO_ERROR) { err =mZip.open("/system/media/bootanimation.zip"); if (err != NO_ERROR) { mAndroidAnimation = true; } } }else { if(!bShutRotate){ status_terr = mZip.open("/data/local/shutanimation.zip"); if (err != NO_ERROR) { err =mZip.open("/system/media/shutanimation.zip"); if (err != NO_ERROR) { mAndroidAnimation = true; } } } }return NO_ERROR;}
readyToRun() 方法判斷/system/media/bootanimation.zip(shutanimaion.zip)是否存在,如果存在,則將 mAndroidAnimation 設定false,這個變數決定threadLoop中調用android()還是movie()來具體實現動畫的播放。
boolBootAnimation::threadLoop(){ ........省略........ if(!bBootOrShutDown){ pSoundFileName="/data/local/shutaudio.mp3"; pBackupSoundFileName="/system/media/shutaudio.mp3"; } else { pSoundFileName="/data/local/bootaudio.mp3"; pBackupSoundFileName="/system/media/bootaudio.mp3"; } if (mAndroidAnimation) r = android(); } else { r = movie(); }}
threadLoop()方法根據 mAndroidAnimation 變數調用android()/movie(). 如果system/media/shutanimation.zip/bootanimation.zip存在的話,調用movie(),該介面會解析zip檔案中的desc.txt檔案,根據txt檔案中的配置來播放動畫。否則就調用android來播放原生內建的資源。
3、總結
對於圖片資源時如何繪製的,我想這不是本文的重點,有興趣的同學可以繼續深究,這裡僅僅是拋磚引玉。