【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 )(二)

简介: 【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 )(二)

插件包类加载器是通过创建 DexClassLoader 获得的 , 需要传入插件包中的 dex 字节码类 ;


/**
 * 插件化框架核心类
 */
public class PluginManager {
    /**
     * 类加载器
     * 用于加载插件包 apk 中的 classes.dex 文件中的字节码对象
     */
    private DexClassLoader mDexClassLoader;
    /**
     * 加载插件
     * @param context 加载插件的应用的上下文
     * @param loadPath 加载的插件包地址
     */
    public void loadPlugin(Context context, String loadPath) {
        this.mContext = context;
        // DexClassLoader 的 optimizedDirectory 操作目录必须是私有的
        // ( 模式必须是 Context.MODE_PRIVATE )
        File optimizedDirectory = context.getDir("plugin", Context.MODE_PRIVATE);
        // 创建 DexClassLoader
        mDexClassLoader = new DexClassLoader(
                loadPath, // 加载路径
                optimizedDirectory.getAbsolutePath(), // apk 解压缓存目录
                null,
                context.getClassLoader() // DexClassLoader 加载器的父类加载器
        );
    }
    /**
     * 获取类加载器
     * @return
     */
    public DexClassLoader getmDexClassLoader() {
        return mDexClassLoader;
    }
}





二、" 宿主 " 模块加载 " 插件 " 模块中的资源文件


在 " 宿主 " 模块中 , 使用 Resources 是无法获取到 " 插件 " 模块中的资源文件的 , 在使用 " 插件 " 模块中的资源文件之前 , 必须先加载其中的资源文件 ;


/**
 * 该 Activity 只是个空壳 ;
 * 主要用于持有从 apk 加载的 Activity 类
 * 并在 ProxyActivity  声明周期方法中调用对应 PluginActivity 类的生命周期方法
 */
public class ProxyActivity extends AppCompatActivity {
    /**
     * 需要使用插件包中加载的资源
     * @return
     */
    @Override
    public Resources getResources() {
        return PluginManager.getInstance().getmResources();
    }
}



插件包中的 Resources 加载过程如下 :


首先 , 通过反射创建 AssetManager ,

然后 , 通过反射获取 AssetManager 中的 addAssetPath 隐藏方法 ,

再后 , 调用 AssetManager 的 addAssetPath 方法 ,

最后 , 通过 AssetManager 创建 Resources 对象 ;


/**
 * 插件化框架核心类
 */
public class PluginManager {
    /**
     * 加载插件
     * @param context 加载插件的应用的上下文
     * @param loadPath 加载的插件包地址
     */
    public void loadPlugin(Context context, String loadPath) {
        this.mContext = context;
        // 加载资源
        try {
            // 通过反射创建 AssetManager
            AssetManager assetManager = AssetManager.class.newInstance();
            // 通过反射获取 AssetManager 中的 addAssetPath 隐藏方法
            Method addAssetPathMethod = assetManager.
                    getClass().
                    getDeclaredMethod("addAssetPath");
            // 调用反射方法
            addAssetPathMethod.invoke(assetManager, loadPath);
            // 获取资源
            mResources = new Resources(
                    assetManager,
                    context.getResources().getDisplayMetrics(),
                    context.getResources().getConfiguration()
            );
        } catch (IllegalAccessException e) {
            // 调用 AssetManager.class.newInstance() 反射构造方法异常
            e.printStackTrace();
        } catch (InstantiationException e) {
            // 调用 AssetManager.class.newInstance() 反射构造方法异常
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // getDeclaredMethod 反射方法异常
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // invoke 执行反射方法异常
            e.printStackTrace();
        }
    }
    /**
     * 获取插件包中的资源
     * @return
     */
    public Resources getmResources() {
        return mResources;
    }
}








目录
相关文章
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
94 6
|
2月前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
33 3
|
2月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
29 3
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
21 0
|
3月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
61 0
|
7月前
|
数据库 Android开发 开发者
Android基础知识:请解释Activity的生命周期。
Android基础知识:请解释Activity的生命周期。
79 2
|
6月前
|
Android开发 UED
Android Activity的生命周期详解
Android Activity的生命周期详解
|
7月前
|
Android开发
Android Studio APP开发入门之活动Activity中启停活动页面的讲解及实战(附源码,包括Activity的启动结束、生命周期、跳转等)
Android Studio APP开发入门之活动Activity中启停活动页面的讲解及实战(附源码,包括Activity的启动结束、生命周期、跳转等)
140 0
|
Android开发
Android 中Activity和Fragment生命周期的具体变化详解
Android 中Activity和Fragment生命周期的具体变化详解
222 0