美文网首页
插件化方案

插件化方案

作者: 拿拿guardian | 来源:发表于2020-05-20 15:58 被阅读0次

    一、将插件化内容打包成apk,放在宿主APP的assert目录下。
    二、app启动时,动态加载插件apk的内容:

    • 将插件apk复制到/data/user/0/packagename/app_apk 目录下
    • 用DexClassLoader从插件apk的提取dex文件,保存在/data/user/0/packagename/app_dex目录
    private DexClassLoader createDexClassLoader(String pluginName) {
            
            boolean saved = savePluginApkToStorage(pluginName);
            if(!saved) {
                return null;
            }
            
            DTLog.d(TAG, "createDexClassLoader pluginName = " + pluginName);
            
            DexClassLoader classLoader = null;
            
            try {
                
                String apkPath = this.getPlguinApkDirectory() + pluginName;
                
                File dexOutputDir = DTApplication.getInstance().getDir("dex", 0);
                
                String dexOutputDirPath = dexOutputDir.getAbsolutePath();
                
                Log.d(TAG, " apkPath = " + apkPath + " dexOutputPath = " + dexOutputDirPath);
                
                ApplicationInfo ai = DTApplication.getInstance().getApplicationInfo();
                String nativeLibraryDir = null;
                if (Build.VERSION.SDK_INT > 8) {
                    nativeLibraryDir = ai.nativeLibraryDir;
                } else {
                    nativeLibraryDir = "/data/data/" + ai.packageName + "/lib/";
                }
                
                DTLog.d(TAG, " native library path = " + nativeLibraryDir);
                
                ClassLoader cl = DTApplication.getInstance().getClassLoader();
                
                DTLog.d(TAG, " get parent class loader = " + cl.getParent());
                
                classLoader = new DexClassLoader(apkPath, dexOutputDirPath, nativeLibraryDir,  
                        cl);  
                
                Log.d(TAG, "after new class loader classLoader = " + classLoader.toString());
            
            }catch(Throwable e) {
                
                //Assert.assertTrue("LoadPluginApk e=" + ExceptionUtils.getStackTrace(e), false);
                //DTLog.e(TAG, "loadPluginApk exception = " + ExceptionUtils.getStackTrace(e));
            }
            
            DTLog.d(TAG, "End load apk");
            
            return classLoader;
            
        }
    

    三、将步骤二中生成的DexClassLoader实例保存下来,代码运行时用到插件apk的内容时,直接用保存下来的DexClassLoader实例去加载相关class文件:

        public Object newInstance(String className) {
            
            if(mDexClassLoader == null) {
                return null;
            }
            
            try {
                Class<?> clazz = mDexClassLoader.loadClass(className);
                Object instance = clazz.newInstance();
                return instance;
            } catch (Exception e) {
                DTLog.e(TAG, "newInstance className = " + className + " failed" + " exception = " + e.getMessage());
            }
            
            return null;
        }
    

    相关文章

      网友评论

          本文标题:插件化方案

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