android动态加载activity

这个技术常用于android插件开发,android加固,,,,(妈的,抄第一代壳的时候,死活看不懂,原来是因为没看过这技术。。),
我还得补一补,,,
classloader
类加载器,听名字就知道用于加载类的,对于安卓层面的话,就是用于加载dex文件
双亲委派
加载dex文件的时候,问一下当前的类加载器有没有加载,没的话,递归问类加载器的超类,这一继承路上,只要dex文件被其中一个classloader加载,其他时候都不用被加载

android的类加载器

1.bootclassloader(加载android框架的)
2.pathclassloader(加载安装到android上的apk文件)
3.dexclassloader(可以加载自己的dex文件),动态加载的关键点
4.baseclassloader(pathclassloader和dexclassloader的父类)

pathclassloader和dexclassloader区别
其实没什么区别,毕竟父类都是baseclassloader,唯一区别在于dexclassloader比pathclassloader多一个存放自己dex文件的参数,
用于加载classloader的时候

// PathClassLoader
public class PathClassLoader extends BaseDexClassLoader {
    public PathClassLoader(String dexPath, ClassLoader parent) {
        super(dexPath, null, null, parent);
    }

    public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        super(dexPath, null, librarySearchPath, parent);
    }
}
// DexClassLoader
public class DexClassLoader extends BaseDexClassLoader {
    public DexClassLoader(String dexPath, String optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        super(dexPath, new File(optimizedDirectory), librarySearchPath, parent);
    }
}

类加载器如何判断当前的dex文件是否被加载过呢?
findclass方法,看了几篇文章,明白了原理,就是一条一环套一环的线
pathclassloader和dexclassloader都是用它的父类(baseclassloader)的findclass方法,而baseclassloader的findclass方法主要来自dexpathlist的findclass方法,而dexpathlist的findclass方法主要就是对它dexelement集合的遍历查找,而dexelement是来源于makedexelements方法

private static Elempublic class BaseDexClassLoader extends ClassLoader {
    private final DexPathList pathList;
    ...
    public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent){
        super(parent);
        this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
    }
    ...
}
ent[] makeDexElements(ArrayList<File> files, File optimizedDirectory, ArrayList<IOException> suppressedExceptions) {
    // 1.创建Element集合
    ArrayList<Element> elements = new ArrayList<Element>();
    // 2.遍历所有dex文件(也可能是jar、apk或zip文件)
    for (File file : files) {
        ZipFile zip = null;
        DexFile dex = null;
        String name = file.getName();
        ...
        // 如果是dex文件
        if (name.endsWith(DEX_SUFFIX)) {
            dex = loadDexFile(file, optimizedDirectory);

        // 如果是apk、jar、zip文件(这部分在不同的Android版本中,处理方式有细微差别)
        } else {
            zip = file;
            dex = loadDexFile(file, optimizedDirectory);
        }
        ...
        // 3.将dex文件或压缩文件包装成Element对象,并添加到Element集合中
        if ((zip != null) || (dex != null)) {
            elements.add(new Element(file, false, zip, dex));
        }
    }
    // 4.将Element集合转成Element数组返回
    return elements.toArray(new Element[elements.size()]);
}

可以看到,加载文件,并将它分装成element对象。放到elements数组里,而makedexelements是在dexpathlist的构造函数中调用,而dexpathlist的构造在baseclassloader的构造函数中创建,而baseclassloader的创建是在我们用dexclassloader和pathclassloader中使用,
由此我们可以理清楚android加载dex文件的流程:
当我们使用dexclassloader加载dex文件时,dexclassloader调用它的超类baseclassloader,
而baseclassloader由此new dexpathlist,接着dexpathlist使用makedexelements方法加载dex文件,同时将加载好后的文件包装成elements中去,而类加载器使用findclass判断是否加载过该dex文件时,正是通过对elements集合的遍历查找

mclassloader来源于loadedapk.java,可以知道这个loadedapk用于加载apk文件的,而loadedapk对象

有了以上知识,就可以谈一下我们的重点 动态加载activity,ActivityThread类中有一个自己的static对象,然后还有一个ArrayMap存放Apk包名和LoadedApk映射关系的数据结构,

android的动态加载activity

使用反射机制修改类加载器来实现动态加载Activity

1.替换LoadedApk中的mClassLoader
2.合并PathClassLoader和DexClassLoader中的dexElements数组
https://blog.csdn.net/suyimin2010/article/details/80958712

静态代理

(不会)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值