Android平台api沒有特意為換膚提供一套簡便的機制,這可能是外國的軟體更注重功能和易用,不流行換膚。系統不提供直接支援,只能自行研究。
換膚,可以認為是動態替換資源(文字、顏色、字型大小、圖片、布局檔案……)。這個使用程式設計語言來動態設定是可以做到的,例如使用View的setBackgroundResource、setTextSize、setTextColor等函數。但我們不可能在每個activity裡對頁面裡的所有控制項都通過調用這些函數來換膚,這樣的程式碼難以維護、擴充,也違背了UI和代碼分離的原則(android開發中UI以xml檔案的方式布局)。 通常,皮膚資源會在主程式apk之外提供,以減少主程式的大小,以及方便隨時提供新的皮膚擴充。
簡單的來說,軟體皮膚包括表徵圖、字型、布局、互動風格等,換膚就是換掉皮膚包括的部分或所有資源。
主流應用程式換膚方式:
國內有很多的軟體都支援皮膚定製,這也是與國外軟體重大不同之一,國外使用者注重社交、郵件等功能,國內使用者則重視音樂、小說、皮膚等功能. 在寫這個換膚系列之前,我也參考了其他人的一些總結. 知識點比較散,因此我對其進行了整理和進一步的最佳化和擴充. 當然,由於精力有限,部分換膚方式我也唯寫了主體功能的實現. 如果出現有誤或者不夠詳細的地方,希望大家提出意見或者自行進行擴充.
關於其中提到的幾種主流實現方式,接下來的文章裡我會具體提供代碼進行解釋, 此次先做一個整體的概述.
目前主流的換膚從功能上可以劃分幾種實現方式,
1) 軟體內建多個皮膚,不可由使用者增加或修改:
最低的自由度,軟體實現相對於後面的幾種相對簡單.
如果你的程式和資源都很小,可以在主程式apk中放入足夠的皮膚資源.
典型應用:平板電腦Apad上QQ空間的換膚功能,實際上只是改變了Activity的背景,或這部分的資源.
2) 官方提供皮膚供下載,使用者可以使用下載的皮膚:
使用者可選擇下載自己喜歡的皮膚,有些玩家會破解皮膚的定製方法,自己做皮膚使用,或者傳到網上給大家用。
典型應用: 墨跡天氣下載的皮膚就是一個zip格式的壓縮包,在應用的時候把皮膚資源釋放到墨跡天氣應用的目錄下,更換皮膚時新的皮膚資源會替換掉老的皮膚資源每次載入的時候就是從手機硬碟上讀取圖片,這些圖片資源的命名和程式中的資源的命名保持一致,一旦找不到這些資源,可以選擇到系統預設中尋找。
這種實現是直接讀取了外部資源檔,在程式運行時通過代碼顯示的替換介面的背景資源。
這種方式的優點是:皮膚資源的格式定義很隨意可以是zip也可以是自訂的格式,只要程式中能夠解析到資源就行,缺點是需要讀取並解析檔案,導致效率上會比較差.
3) 皮膚資源存在於主程式之類的APK中,即實現了APK的拆分. 這裡類似於瀏覽器與外掛程式的關係. 當考慮應用程式需要擴充時,則需要採用本方式實現.,這不僅僅體現在換膚的APK中.
典型應用: 手機QQ換膚的實現方式
QQ的皮膚是一個無介面APK應用,這個皮膚應用中的資源和主程式的資源命名一致,通過主程式和皮膚程式共用進程實現主程式對皮膚程式中資源的訪問,在程式運行時通過代碼顯示指定皮膚資源,缺點是在主程式中每個activity要增加複雜的使用哪種皮膚邏輯,優點是效率比較快,且使應用程式具有了良好的擴充性,降低了程式的耦合性. 包括其他類似的擴充功能,都可以利用此方式實現.
4) 官方提供皮膚製作工具或方法,使用者可自製皮膚:
大致分為兩種情況:
1. 應用程式主列表為一個GridView,使用者可通過在設定中選擇背景的顏色和按鈕的風格. 直接進行替換即可.
2. 另外一種是有可視化帶嚮導的工具。使用者只要自己找一些圖片、修改文字的字型替代就可以了。使用者可以上傳自製的皮膚,提供其他使用者下載. 一般都是打包為.zip格式的,副檔名可由公司需求自訂. 例如墨跡天氣皮膚副檔名是mja,搜狗IME的皮膚副檔名是sga,它們的檔案格式實際上都是zip。之後的應用就和第二種換膚方式類似了.
這種方式優點是:使使用者有參與感,自由度較高。使用者可根據自己的喜好定製軟體的皮膚。
5) 改寫SDK的Resource類:
在今年二月二十九號的CMDN的一個活動上小米MIUI系統工程師董紅光發表了Android系統MIUI底層換膚技術的主題演講,提到了小米主題更換是改寫SDK的 Resource類,這種方式需要熟悉Android系統的FrameWork層,因此實現比較複雜,花費較大的精力進行研究.
此處提供一些思路:
在Android系統中,資源主要指圖片和MP3類型的檔案,也是使用者UI包含的所有元素。Google在設計Android系統時,將UI介面和邏輯代碼分開組建:介面設計通過XML的形式描述,具體的程式和應用邏輯則通過代碼來實現;前端工程師只負責HTML和CSS的設計與架構,後端工程師則專門考慮JSP和Java的代碼執行.
資源訪問在Android效能架構中處於何種地位?在進行Android開發時,開發人員經常用到Framework提供的資源套件Framework.jar與Framework-res.apk,以及與核心資源相關的組件“Resource Manager”檔案系統。
APK本身是一個簡單的檔案格式,也是一個壓縮檔包。通過解壓檔案包可以釋放APK檔案:首先需要APK的原資料Meta INF、Manifest以及RES目錄。一部分包含圖片資源的應用,在資源釋放時也會用到Layout。
在安裝檔案時,系統會將檔案取出、解壓後放在Dalvik Cache中。該緩衝下有許多dex檔案,當使用者開啟應用時系統會自動載入相應的類。在載入過程中,系統如需訪問APK,則需對其進行解壓,這樣通常導致效率較為低下。而如果將dex檔案放入Dalvik Cache中,則能夠令載入的效率大大提升。
每個進程都有一份關於Framework的共用類和共用資源,但實體記憶體空間中的系統層級資源只有一份。Framework類和資源是唯讀,而Android作業系統設計之初並沒有硬碟的虛擬記憶體和換進換出機制,所以節省記憶體空間是非常重要的工作。