研究了幾種android換膚的策略,感受apk方式比較容易管理資源,代碼改造量還算小,可是apk模式在大量使用style和系統級style的項目中,不能靈活應用,並且每次加載頁面都須要判斷一下是否須要替換皮膚,可能還需深刻研究一下。
java
最開始因爲沒有考慮apk皮膚安裝時候會彈出確認框的問題,因此先基於安裝apk查詢資源的方法作了開發。android
apk資源文件名稱和主工程資源名保持一致。測試
第一步獲取皮膚apk的Context。.net
private Context getThemeContext(Context context) { Context c = null; try { c = context.createPackageContext("皮膚apk的包名", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e) { e.printStackTrace(); c = context; } return c; }
皮膚apk的包名也能夠經過搜索手機所有安裝apk的包名來查找,先查出你皮膚的包名,而後再獲取相應的Context。
code
public ArrayList<PackageInfo> getAllSkin() { ArrayList<PackageInfo> skinList = new ArrayList<PackageInfo>(); List<PackageInfo> packs = mContext.getPackageManager().getInstalledPackages(0); for (PackageInfo p : packs) { if (isSkinPackage(p.packageName)) { skinList.add(p); } } return skinList; } private boolean isSkinPackage(String packageName) { String rex = "com.test.huoyun.theme\\w"; Pattern pattern = Pattern.compile(rex); Matcher matcher = pattern.matcher(packageName); return matcher.find(); }
第二部 獲取相應皮膚APK中的資源ID,開始作測試就2張圖片,用皮膚apk的Context.getResources方法獲取資源,能夠正常獲取到,可是若是皮膚資源和主工程資源不統一的話,那就會出現找不到資源ID的錯誤,blog
這裏是由於主工程生成的R中的ID與皮膚資源不一樣。因此須要經過getIdentifier方法獲取皮膚包中的資源ID圖片
private int getInstallApkResourcesID(Context themeContext,int id) { //type name是R.drawable.background中的"drawable",entry name是"background" String resEntryName = mContext.getResources().getResourceEntryName(id); String resTypeName = mContext.getResources().getResourceTypeName(id); int rid = themeContext.getResources().getIdentifier(resEntryName, resTypeName, themeContext.getPackageName()); return rid; }
這樣基本就能夠獲取皮膚apk中的資源了。資源
以上是經過安裝了皮膚apk方式獲取皮膚資源。開發
下面一篇是不安裝皮膚apk,只是經過apk管理資源的方法。get