VirtualAPK的简单梳理
最近某个项目使用到了插件化,突然想起来之前一直想好好学习下插件化,总是忘记,刚好借着这个机会好好研究一下。 这里就根据滴滴的VirtualAPK进行解析吧,基本原理都大同小异。 滴滴开源项目的源码: https://github.com/didi/VirtualAPK 可以直接下载,想要深入理解插件化技术,还需要配合AOSP进行解析,Android官网给出的下载建议是在Linux上下载,一般个人的话都是自己电脑配置的虚拟机,申请60多G的磁盘空间有点难受,Windows下载的话不仅慢,也要很大的磁盘空间,因此我找到了一个在线查看Android源码的网站: https://www.androidos.net.cn/android/9.0.0_r8/xref/frameworks 在线阅读,看起来非常方便233333 接下来就是插件化小白的入门之旅!!
先从最最基本的Activity入手: 经过一些两步传递之后进行到这个函数: mParent不为null时调用的是 但最后调用的都是Instrumentation的execStartActivity 其中Instrumentation为工具类,mMainThread的类型是ActivityThread,getApplicationThread是其静态内部类, execStartActivity的实现在Instrumentation.java中: 最后调用了ActivityManager.getService() .startActivity,这个方法涉及到有关于Binder的跨进程通信,在AMS记录并处理了相关信息后,会回调到应用进程,通过ApplicationThread类中的scheduleLaunchActivity方法启动Activty,具体的细节不在本篇文章的分析范围中,不做详细介绍, 我从网上找了一个关于进程信息的概括图,很方便于理解:
大体流程梳理下来,发现虽然启动一个Activity的前提是Activity需要在Manifest.xml中注册,但是我们可以用一个假的Activity占坑,在于Activity交互之前把名字替换为这个假的activity,等到真的去创建Activity的时候,是由我们app进程自己决定的,完全可以去创建插件的Activity,系统不会感知到这个行为,这么想的话,我们有两个hook点,Instrumentation或者是ActivityManagerProxy,VirtualAPK选择了Instrumentation。 VAInstrumentation中在execStartActivity之前将intent中的名字进行了替换: 其中这个stubActivity就是用来欺骗AMS的Activity 等到AMS回调到app进程后,我们将之前准备好的真正的需要加载的Activity替换上: Activcty组件的替换,主要在于hook了execStartActivity函数和new Activity,前者已分析过,后者其实是在performLaunchActivity中调用的:
还有一个有意思的点,源码工程里还有一个AndroidStub package,其中这部分diamante的作用是我们得到Irstrumentation是通过getInstrumentation()得到的,但是ActivityThread是hide的,这个百度了一下:
加入了 /** {@hide} */ 注视后的类或者API是google编译时不对外开放的,但是运行的时候这写类和API都是可以访问的 因此通过上述方法就可以调用getInstrumentation(),同时能保证编译时不报错了。
这篇文章只梳理了四大组件中的Activity,很多地方说的不够详细,逻辑可能也不对。第一次写博客,希望以后能保持这个习惯,把自己平时所学的记录下来,以后会尽力说的更详细,更加准确。