天天看點

android 換膚 apk

在android系統中,每一個application是一個程序和一個使用者,不同的程序間是不能互相通路的。如果想讓兩個程式之間可以互相通路其資源,就可以讓這兩個apk運作在同一個程序裡就可以。要讓兩個apk運作在同一個程序裡,要滿足兩個條件:相同的sharedUserId和用相同的證書進行簽名

  預設情況下,如果不配android:sharedUserId,則其userid與包名相同,是以我們可以把皮膚包的android:sharedUserId與主apk配置的相同,再用相同的簽名打包,就可以共享資源。

  以上是打皮膚包方法,但真正把這個方案用在複雜一點的項目裡時,問題會很多。比如按照上面的方法,在主apk裡怎樣擷取皮膚包的圖檔:

android 換膚 apk

try {  

    mSkin1Context = this.createPackageContext("com.ly.skin1", CONTEXT_IGNORE_SECURITY);  

} catch (NameNotFoundException e) {  

    mSkin1Context = this;  

}  

Drawable drawable = mSkin1Context.getResources().getDrawable(R.drawable.image1);  

 用上面的方法有一個要求,就是在主程式和皮膚程式裡都要有image1圖檔,但這兩張圖檔的内容是不一樣的。

  這樣感覺隻要資源的名稱相同就行了,但關鍵是R.drawable.image1是一個常量,在編譯階段會用常量的值替換掉這個變量,問題就出來了,盡管主apk和皮膚包有相同名稱的圖檔,但如果他們的值不一樣,則也會出錯。

  R檔案裡的常量的值不是隻與其本身資源的名稱有關,還與所有的圖檔名稱有關,隻有保證皮膚包和主apk有完全相同的圖檔名稱(所有),才能保證其生成的常量的值也相同。

針對上面的問題的解決辦法:

  如果不想皮膚包太大,可以用item屬性:

android 換膚 apk

<item type="drawable" name="icon"/>  

<item type="drawable" name="image1"/>  

<item type="drawable" name="image3"/>  

這樣也可以在R檔案裡的Drawable類裡添加上面三個常量。

注意:上面的三個圖檔,icon,image1,image3可以在資源檔案裡已經存在了,也可以在這裡再寫一遍,但其他的layout屬性不可以這樣做,隻能寫沒有出現過的。

共享layout檔案

  上面隻講了換圖檔方法,即然是資源全部共享,其實還可以共享其layout檔案,這樣可以改變其布局檔案,包括字型顔色和位置。

  同樣的問題,R.layout.xxx也是常量,在編譯期間都會替換成數值,為了保證其生成的常量的值都相同,我們可以讓皮膚包和主apk的布局檔案一樣,也可以用上面的item标簽,但注意item裡的與layout裡的,不能重複,但drawable可以。

  還有一個問題就是id值,id值也可以在item裡寫,這樣在其他的layout檔案裡就不要用@+id/xxx,直接用@id/xxx就可以了,但我測出一個問題,如果把id全部都寫在layout檔案裡,和全部都寫在item裡,其常量的值不一樣,是以隻能選一樣方法。

講講用這種方法進行換膚的缺點:

   1. 由于其常量的值與整個資源都有關系,是以一個皮膚包隻能與一個特定的版本相關聯,每個版本都要用其獨立的皮膚包,以前的不能重用,因為在新的版本裡,其資源一般都會發生變化。

   2. 如果想讓皮膚包小一點話,就要為不能的手機分辨率打不同的apk包

   3. 由于不同的版本之間不能共用皮膚包,是以使用者更新新版本後,隻有手動才能把老的皮膚包删除掉,但使用者區分哪個是老的皮膚包,比較麻煩。

   4. 為了維護的友善,一般是把每個版本擁有的皮膚包的位址寫死在用戶端。

繼續閱讀