美文网首页
插件机制之资源管理

插件机制之资源管理

作者: 搬砖写Bug | 来源:发表于2018-10-17 17:03 被阅读21次

    <未完成,待续>

    获取未安装 apk (插件)的 Resource

    因为没有安装,所以不能得到 context,所以我们需要未安装 apk 的 Resource,我们可以通过反射来获取,代码如下

        /** 
         * @param apkPath  
         * @return 得到对应插件的Resource对象 
         */  
        private Resources getPluginResources(String apkPath) {  
            try {  
                AssetManager assetManager = AssetManager.class.newInstance(); 
                //反射调用方法addAssetPath(String path)
                Method addAssetPath = assetManager.getClass().getMethod(ADDSSETPATH, String.class);  
                //将未安装的Apk文件的添加进AssetManager中,第二个参数是apk的路径  
                addAssetPath.invoke(assetManager, apkPath);
                Resources superRes = this.getResources();  
                Resources mResources = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());  
                return mResources;  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            return null;  
        }
    

    用DexClassLoader加载apk资源文件替换背景

        /** 
         * 加载apk获得内部资源,并且替换背景
         * @param apkDir apk目录 
         * @param apkName apk名字,带.apk 
         * @throws Exception 
         */  
        private void dynamicLoadApk(String apkPath, String apkPackageName) throws Exception {
            //在应用安装目录下创建一个名为app_dex文件夹目录,如果已经存在则不创建,这个目录主要是最优化目录,用于缓存dex文件
            File optimizedDirectoryFile = getDir(DEX, Context.MODE_PRIVATE); 
            //打印路径 理论上是/data/data/package/app_dex
            Log.v(TAG, optimizedDirectoryFile.getPath().toString());  
            //构建DexClassLoader
            DexClassLoader dexClassLoader = new DexClassLoader(apkPath, optimizedDirectoryFile.getPath(), null, ClassLoader.getSystemClassLoader());  
            //通过使用apk自己的类加载器,反射出R类中相应的内部类进而获取我们需要的资源id
            Class<?> clazz = dexClassLoader.loadClass(apkPackageName + DRAWABLE);  
            //得到名为about_log的这张图片字段,这个图片是为安装apk里面的图片
            Field field = clazz.getDeclaredField(IMAGE_ID); 
            //得到图片id  
            int resId = field.getInt(R.id.class);
            //得到插件apk中的Resource  
            Resources mResources = getPluginResources(apkPath);
            if (mResources != null) {  
                //通过插件apk中的Resource得到resId对应的资源  
                Drawable btnDrawable = mResources.getDrawable(resId);
                mLayout.setBackgroundDrawable(btnDrawable);   
            } else {
                Log.d(TAG, "mResources is null");
            }
        }
    

    reference:
    Android插件化开发之用DexClassLoader加载未安装的APK资源文件来实现app切换背景皮肤

    相关文章

      网友评论

          本文标题:插件机制之资源管理

          本文链接:https://www.haomeiwen.com/subject/yknhzftx.html