在上一篇文章中,我們大緻的介紹了recovery的啟動流程,那麼,recovery更新或者做雙清的時候,那些圖形動畫又是如何實作的呢?我們來看看代碼:
以下這段代碼位于recovery/screen_ui.cpp
這段代碼都做了哪些事情呢?這些recovery初始化圖形顯示最開始的部分,
(1)調用了miniui中的gr_init初始化顯示圖形相關的步驟,因為recovery是基于framebuffer機制顯示的。
(2)調用gr_font_size設定字型顯示的大小,然後計算文本顯示行列。
(3)接下來就是裝載圖檔了,會調用到LoadBitmapArray和LoadBitmap這兩個函數。其中,我們會看到這些函數裡圖檔的名稱:
"icon_installing"、"icon_error"、"progress_empty"、"progress_fill"、
"stage_empty"、"stage_fill"、"installing_text"、"erasing_text"、
"no_command_text"、"error_text"
将上面的字元串與下面的圖檔一一對應:
那麼這些分别是怎麼顯示的?其中erasing_text是用來顯示做清除的時候顯示的文字,放大後如下:
這上面有許許多多的語言版本,我們可以根據需要來選擇,這些主要要看接下來初始化文字的代碼邏輯。
其餘的圖檔中,字尾帶text的,也和這些是類似的,有出現錯誤顯示的字型error_text,更新系統顯示的字型installing_text,沒有指令的時候顯示的字型no_command_text。
除了文字顯示,我們最關心的就是icon_installing這張圖檔了,在做系統更新的時候,這個機器人會轉動。這不是動畫嗎?怎麼隻有一張圖檔呢?我們找到Android官方網站看看是為什麼?
原因如下:
Recovery UI images
Android 5.x
The recovery user interface consists images. Ideally, users never interact with the UI: During a normal update,
the phone boots into recovery, fills the installation progress bar, and boots back into the new system without
input from the user. In the event of a system update problem, the only user action that can be taken is to
call customer care.An image-only interface obviates the need for localization.
However, as of Android 5.x the update can display a string of text (e.g. "Installing system update...")
along with the image. For details, see Localized recovery text.
efault images are available in different densities and are located inbootable/recovery/res$DENSITY/images
(e.g., bootable/recovery/res-hdpi/images). To use a static image during installation,
you need only provide the icon_installing.png image and set the number of frames in the animation to 0
(the error icon is not animated; it is always a static image).
// 以上文檔意思就是說,Android5.x以上的版本,機器人的動畫是PNG圖檔和幀動畫組成的,
//我們可以使用recovery目錄下的interlace-frames.py這個python腳本來進行合成,
//具體的合成方法需要使用recovery代碼中的一個python合成工具。
//我就可以把android原生态的動畫給換了,因為這個機器人實在是醜。
源碼如下:
這也就是為什麼,調用這張圖檔需要用到LoadBitmapArray這個函數的原因。
調完這個函數後會調用resources.cpp中的res_create_multi_display_surface函數用于顯示,源碼如下:
其餘的和text無關圖檔,會用到LoadBitmap這個函數:
同樣調用到以下函數:
關于圖檔我們大概都知道怎麼來顯示的了,是以,現在我們可以替換Android原生态中的圖檔,換成我們自己的圖檔,
當然,也不是什麼圖都可以的,在recovery中,所有的png圖檔必須是RGB且不帶且不能帶alhpa通道資訊。
關于這一點,我們可以看open_png這個函數:
在代碼中,我們可以看到如下:
以下參考一位網友給出的答案。
這個函數将圖檔檔案的資料讀取到記憶體,我在其中輸出了一些調試資訊,輸出圖檔的 color_type, channels 等資訊。
檢視LOG發現,android原生的圖檔 channels == 3,channels 即色彩通道個數,等于 3 的話,意味着隻有 R,G,B 三個通道的資訊,
沒有 ALPHA 通道資訊!這段代碼的邏輯是如果channels 不等于3, 則按channels = 1 來處理,即灰階圖。
美工給的圖檔是帶 alpha通道資訊的,即channels = 4,被當成灰階圖像來處理了,怪不得顯示的效果是灰階圖像。
我一直以為 png 圖像就隻有一種格式,都是帶有 alpha通道的。。。
使用圖像處理工具(photoshop 或者 gimp),将美工給的圖檔去掉 alpha 通道資訊,再替換recovery 的圖檔,編譯,替換recovery.img ,
reboot -r 。圖檔終于正常顯示啦。
在下一節裡,我們将繼續分析UI顯示....