Replugin 学习笔记

在Replugin 这个框架中,360实现了只需要hook一个点,就可实现插件化加载,而这个点就是classloader。为什么hook这个点就能解决Activity 动态加载的问题,这个就要从我们的Activity是怎么来的说起了,Activity的启动代码相当复杂,在这里就不分析了,网上有不少大神的blog都分析了这个问题,其中跟hook点最相关的就是下面的这一段。
这一段从ActivityThread的 performLaunchActivity 方法中摘出,

Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }

进入mInstrumentation 的 newActivity 方法:

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

看到这个方法是不是就有一种恍然大悟的感觉了,最终的Activity 实例是通过其 Activity 的class对象调用newInstance()得到的. 所以只需要控制了 Activity的class 对象, 就控制了Activity的产生,而这个class对象,正是我们可以通过hooK来解决的。

在这里Relugin 框架解决了Activity 怎么来的问题,同时因为Activity需要在AndroidManifest中注册,所以在使用Replugin 框架的时候,框架的插件会在生成的Apk文件中添加很多的Activity组件来作为一个个占坑,比如当我们启动的一个Activity A 的时候,Relugin 会将我们的目标Activity替换为坑位中的一个Activity AP ,但是在实际返回这个Activity目标class 对象的时候,返回的却是Activity A 的class 对象。

走完这个流程,Replugin 的核心原理应该就算是掌握了,虽然说得这么简单,但是其中每个步骤都相当的复杂,继续学习吧。

具体实现可以看下demo