美文网首页
插件化方案

插件化方案

作者: 拿拿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