插件化方案

2020-05-20  本文已影响0人  拿拿guardian

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

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;
    }
上一篇下一篇

猜你喜欢

热点阅读