Android資源動(dòng)態(tài)加載思路

在很多Android應(yīng)用上必孤,都有資源動(dòng)態(tài)加載的功能猾骡,比如更換主題皮膚,替換聊天界面背景圖片等敷搪。

微信更換聊天窗口背景

以微信為例兴想,當(dāng)用戶選擇模板時(shí),會(huì)先從網(wǎng)絡(luò)上下載相應(yīng)的圖片資源赡勘,然后再替換為聊天界面的背景圖片嫂便。我們知道,應(yīng)用中的資源文件狮含,包括圖片顽悼,xml文件等,都是在編譯的時(shí)候打包好的几迄,那怎樣才能動(dòng)態(tài)加載資源呢蔚龙?

其實(shí)有一個(gè)比較簡(jiǎn)單的思路,將需要替換的資源文件打包在一個(gè)apk文件中映胁,動(dòng)態(tài)下發(fā)到本地木羹,然后通過重新構(gòu)造Resources對(duì)象訪問apk中的資源,進(jìn)行本地的動(dòng)態(tài)替換。主要有以下幾個(gè)步驟:

一坑填、指定資源文件加載路徑

Android應(yīng)用中的資源是通過AssetManager來管理的抛人,其中addAssetPath方法可以指定資源加載路徑。

/** 
  * Add an additional set of assets to the asset manager. This can be 
  * either a directory or ZIP file.  Not for use by applications.  Returns 
  * the cookie of the added asset, or 0 on failure. 
  * {@hide} 
  */
 public final int addAssetPath(String path) {    
     synchronized (this) {        
         int res = addAssetPathNative(path);           
         makeStringBlocks(mStringBlocks);        
         return res;    
     }
 }

很顯然這是個(gè)隱藏的API脐瑰,所以需要通過反射來調(diào)用妖枚。

private AssetManager createAssetManager(String skinFilePath) {  
    try {        
        AssetManager assetManager = AssetManager.class.newInstance();        
        Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);        
        addAssetPath.invoke(assetManager, skinFilePath);        
        return assetManager;    
    } catch (Exception e) {        
       e.printStackTrace();        
       return null;    
    }
}

二、構(gòu)造Resources對(duì)象

private Resources createResources(Context context, AssetManager assetManager) {    
    Resources superRes = context.getResources();    
    Resources resources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());      
    return resources;
} 

有了Resource對(duì)象苍在,就可以訪問指定路徑的資源文件绝页,進(jìn)行動(dòng)態(tài)替換,示例如下:

public class SkinManager {
    private Resources mResources;
    /**
     * 獲取APK資源
     * @param context 上下文
     * @param apkPath APK路徑
     */
    public void loadSkinRes(Context context, String skinFilePath) {
        if (TextUtils.isEmpty(skinFilePath)) {
            return ;
        }
        try {
            AssetManager assetManager = createAssetManager(skinFilePath);
            mResources = createResources(context, assetManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private AssetManager createAssetManager(String skinFilePath) {
        try {
            AssetManager assetManager = AssetManager.class.newInstance();
            Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
            addAssetPath.invoke(assetManager, skinFilePath);
            return assetManager;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private Resources createResources(Context context, AssetManager assetManager) {
        Resources superRes = context.getResources();
        Resources resources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
        return resources;
    }

    public Resources getSkinResource() {
        return mResources;
    }
}

在進(jìn)入Activity的時(shí)候進(jìn)行檢查寂恬,如果有資源apk文件续誉,則通過新的Resources對(duì)象進(jìn)行資源獲取。

public class MainActivity extends Activity {

    private Context mContext;
    private ImageView mBgView;
    private SkinManager mSkinManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBgView = (ImageView) findViewById(R.id.bg);
        mContext = this;
        mSkinManager = new SkinManager();
        checkNewSkin();
    }

    private void checkNewSkin() {
        String skinDir = "/mnt/sdcard/skin";
        File file = new File(skinDir);
        File[] skinFile = file.listFiles();
        if (skinFile == null || skinFile.length == 0) {
            return ;
        }
        mSkinManager.loadSkinRes(mContext, skinFile[0].getAbsolutePath());
        if (mSkinManager.getSkinResource() != null) {
            mBgView.setBackgroundDrawable(mSkinManager.getSkinResource().getDrawable(R.mipmap.skin));
        }
   }
}

這里是非常簡(jiǎn)單的處理初肉,將編譯好的資源apk文件push到本地sd卡直接加載酷鸦,正常情況下應(yīng)該是從網(wǎng)絡(luò)下載,根據(jù)不同的模板名稱進(jìn)行資源的動(dòng)態(tài)替換牙咏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末臼隔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子妄壶,更是在濱河造成了極大的恐慌躬翁,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盯拱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡例嘱,警方通過查閱死者的電腦和手機(jī)狡逢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拼卵,“玉大人奢浑,你說我怎么就攤上這事∫溉” “怎么了雀彼?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)即寡。 經(jīng)常有香客問我徊哑,道長(zhǎng),這世上最難降的妖魔是什么聪富? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任莺丑,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梢莽。我一直安慰自己萧豆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布昏名。 她就那樣靜靜地躺著涮雷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪轻局。 梳的紋絲不亂的頭發(fā)上洪鸭,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音嗽交,去河邊找鬼卿嘲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛夫壁,可吹牛的內(nèi)容都是我干的拾枣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼盒让,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼梅肤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邑茄,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤姨蝴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后肺缕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體左医,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年同木,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浮梢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彤路,死狀恐怖秕硝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情洲尊,我是刑警寧澤远豺,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站坞嘀,受9級(jí)特大地震影響躯护,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丽涩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一榛做、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦检眯、人聲如沸厘擂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刽严。三九已至,卻和暖如春避凝,著一層夾襖步出監(jiān)牢的瞬間舞萄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工管削, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倒脓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓含思,卻偏偏與公主長(zhǎng)得像崎弃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子含潘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容