魅力程序猿

  • 首页
  • Java
  • Android
  • APP
    • 扑克计分器
    • Video Wallpaper
  • 联系我
  • 关于我
  • 资助
道子
向阳而生
  1. 首页
  2. Android
  3. 正文

Android资源动态加载1

2016年12月5日 5773点热度 0人点赞 2条评论

在很多Android应用上,都有资源动态加载的功能,比如更换主题皮肤,替换聊天界面背景图片等。

我们知道,应用中的资源文件,包括图片,xml文件等,都是在编译的时候打包好的,那怎样才能动态加载资源呢?

其实有一个比较简单的思路,将需要替换的资源文件打包在一个apk文件中,动态下发到本地,然后通过重新构造Resources对象访问apk中的资源,进行本地的动态替换。主要有以下几个步骤:

一、指定资源文件加载路径

Android应用中的资源是通过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;    
     }
 }

很显然这是个隐藏的API,所以需要通过反射来调用。

二、构造Resources对象

有了Resource对象,就可以访问指定路径的资源文件,进行动态替换,示例如下:

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();
        }
    }
    /**
     * 反射addAssetPath方法
     */
    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;
        }
    }
    
    /**
     * 构造Resources对象
     */
    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;
    }
}

三、在进入Activity的时候进行检查,如果有资源apk文件,则通过新的Resources对象进行资源获取。

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));
        }
   }
}

这里只是简单的处理,将编译好的资源apk文件push到本地sd卡直接加载,正常情况下应该是从网络下载,根据不同的模板名称进行资源的动态替换。

 

标签: Android
最后更新:2016年12月5日

daozi

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

  • Bettie

    Great read Anton. Thanks again for taking the time to give us an invrteiew on the beautiful blue lake. I had a fantastic weekend following you and the other runners around with my camera. The finished film will be on YouTube within the next week.

    2016年12月18日
    回复
  • Linx

    I do not fully understand it) Youtube promotion of high production value and grass roots seohis/serws would be a major way for youtube to start matching the revenue of other video websites like hulu. Just think of youtube as an independent cable channel that looks for viewable content that will keep on running.

    2016年12月19日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复
    搜索
    联系方式

    QQ群:179730949
    QQ群:114559024
    欢迎您加入Android大家庭
    本人QQ:136049925

    赐我一丝安慰
    给我一点鼓励

    COPYRIGHT © 2023 魅力程序猿. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    豫ICP备15000477号