上文 Activity生命周期管理 中我们地完成了『启动没有在AndroidManifest.xml中显式声明的Activity』的任务;通过Hook AMS
和拦截ActivityThread中H
类对于组件调度我们成功地绕过了AndroidMAnifest.xml的限制。
但是我们启动的『没有在AndroidManifet.xml中显式声明』的Activity和宿主程序存在于同一个Apk中;通常情况下,插件均以独立的文件存在甚至通过网络获取,这时候插件中的Activity能否成功启动呢?
要启动Activity组件肯定先要创建对应的Activity类的对象,从上文 Activity生命周期管理 知道,创建Activity类对象的过程如下:
1 2 3 4 5
| java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl);
|
也就是说,系统通过ClassLoader
加载了需要的Activity类并通过反射调用构造函数创建出了Activity对象。如果Activity组件存在于独立于宿主程序的文件之中,系统的ClassLoader怎么知道去哪里加载呢?因此,如果不做额外的处理,插件中的Activity对象甚至都没有办法创建出来,谈何启动?
因此,要使存在于独立文件或者网络中的插件被成功启动,首先就需要解决这个插件类加载的问题。
下文将围绕此问题展开,完成『启动没有在AndroidManifest.xml中显示声明,并且存在于外部插件中的Activity』的任务。
阅读本文之前,可以先clone一份 understand-plugin-framework,参考此项目的classloader-hook
模块。另外,插件框架原理解析系列文章见索引。