Android插件化开发之运行未安装apk的activity(2)

简介: Android插件化开发之运行未安装apk的activity(2)

4、合并PathClassLoader和DexClassLoader中的dexElements数组

我们首先来看一下PathClassLoader和DexClassLoader类加载器的父类BaseDexClassloader的源码:

(这里需要注意的是PathClassLoader和DexClassLoader类的父加载器是BaseClassLoader,他们的父类是BaseDexClassLoader)

1.png

这里有一个DexPathList对象,在来看一下DexPathList.java源码:

1.png

Elements数组,我们看到这个变量他是专门存放加载的dex文件的路径的,系统默认的类加载器是PathClassLoader,本身一个程序加载之后会释放一个dex出来,这时候会将dex路径放到里面,当然DexClassLoader也是一样的,那么我们会想到,我们是否可以将DexClassLoader中的dexElements和PathClassLoader中的dexElements进行合并,然后在设置给PathClassLoader中呢?这也是一个思路。我们来看代码:

/**
 * 以下是一种方式实现的
 * @param loader
 */
private void inject(DexClassLoader loader){
  PathClassLoader pathLoader = (PathClassLoader) getClassLoader();
  try {
    Object dexElements = combineArray(
        getDexElements(getPathList(pathLoader)),
        getDexElements(getPathList(loader)));
    Object pathList = getPathList(pathLoader);
    setField(pathList, pathList.getClass(), "dexElements", dexElements);
  } catch (IllegalArgumentException e) {
    e.printStackTrace();
  } catch (NoSuchFieldException e) {
    e.printStackTrace();
  } catch (IllegalAccessException e) {
    e.printStackTrace();
  } catch (ClassNotFoundException e) {
    e.printStackTrace();
  }
}
private static Object getPathList(Object baseDexClassLoader)
    throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
  ClassLoader bc = (ClassLoader)baseDexClassLoader;
  return getField(baseDexClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
}
private static Object getField(Object obj, Class<?> cl, String field)
    throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
  Field localField = cl.getDeclaredField(field);
  localField.setAccessible(true);
  return localField.get(obj);
}
private static Object getDexElements(Object paramObject)
    throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
  return getField(paramObject, paramObject.getClass(), "dexElements");
}
private static void setField(Object obj, Class<?> cl, String field,
    Object value) throws NoSuchFieldException,
    IllegalArgumentException, IllegalAccessException {
  Field localField = cl.getDeclaredField(field);
  localField.setAccessible(true);
  localField.set(obj, value);
}
private static Object combineArray(Object arrayLhs, Object arrayRhs) {
  Class<?> localClass = arrayLhs.getClass().getComponentType();
  int i = Array.getLength(arrayLhs);
  int j = i + Array.getLength(arrayRhs);
  Object result = Array.newInstance(localClass, j);
  for (int k = 0; k < j; ++k) {
    if (k < i) {
      Array.set(result, k, Array.get(arrayLhs, k));
    } else {
      Array.set(result, k, Array.get(arrayRhs, k - i));
    }
  }
  return result;
}

然后运行的时候把MyApplication.java文件里面的函数loadApkClassLoader(mClassLoader);注释掉,然后把MainActivity.java文件里面的inject(MyApplication.mClassLoader)不要注释,运行效果一样。



总结:

我们在使用反射机制来动态加载Activity的时候,有两个思路:


1>、替换LoadApk类中的mClassLoader变量的值,将我们动态加载类DexClassLoader设置为mClassLoader的值


2>、合并系统默认加载器PathClassLoader和动态加载器DexClassLoader中的dexElements数组


这两个的思路原理都是一样的:就是让我们动态加载进来的Activity能够具备正常的启动流程和生命周期。


我们还没解决资源冲突问题,后面再解决,有点复杂。


相关文章
|
1月前
|
移动开发 监控 安全
mPaaS常见问题之Android集成dexPatch热修复运行时候无法正常进行热更新如何解决
mPaaS(移动平台即服务,Mobile Platform as a Service)是阿里巴巴集团提供的一套移动开发解决方案,它包含了一系列移动开发、测试、监控和运营的工具和服务。以下是mPaaS常见问题的汇总,旨在帮助开发者和企业用户解决在使用mPaaS产品过程中遇到的各种挑战
34 0
|
2月前
|
Android开发 开发者
Android Split APK介绍
【2月更文挑战第5天】
|
3月前
|
数据安全/隐私保护 Android开发
2023安卓逆向 -- 某合伙apk登录加密分析
2023安卓逆向 -- 某合伙apk登录加密分析
26 0
|
3月前
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
42 1
|
3月前
|
网络协议 安全 网络安全
Android Termux安装SSH结合内网穿透实现远程SFTP文件传输
Android Termux安装SSH结合内网穿透实现远程SFTP文件传输
48 0
|
1天前
|
Linux 开发工具 Android开发
Docker系列(1)安装Linux系统编译Android源码
Docker系列(1)安装Linux系统编译Android源码
3 0
|
1月前
|
Shell 开发工具 Android开发
ADB 下载、安装及使用教程:让你更好地管理 Android 设备
ADB 下载、安装及使用教程:让你更好地管理 Android 设备
506 2
|
1月前
|
网络协议 关系型数据库 MySQL
安卓手机termux上安装MariaDB数据库并实现公网环境下的远程连接
安卓手机termux上安装MariaDB数据库并实现公网环境下的远程连接
|
2月前
|
算法 数据库 Android开发
安卓逆向 -- APK文件结构
安卓逆向 -- APK文件结构
21 0
|
2月前
|
算法 Java Android开发
安卓逆向 -- 调用其他APK的SO文件
安卓逆向 -- 调用其他APK的SO文件
17 0