框架地址:VirtualApk
在线源码查看:AndroidXRef
关于滴滴插件化框架VirtualApk我们已经讲了有几篇了:
1)插件化框架VirtualApk之初始化
2)插件化框架VirtualApk之插件加载
3)插件化框架VirtualApk之Activity启动
这篇我们紧接着前面开始讲,我们知道启动服务有两种方式startService和bindService两种方式,我们前面已经讲过startService的流程分析和bindService方式的从framework分析AIDL生成文件,而且我们知道,Service
的生命周期是我们可以手动控制的,我们可以不像Activity
生命周期的控制一样交给系统管理,我们可以更简单地控制Service
的生命周期。
Service生命周期
我们看到Service的生命周期是比较简单的,而且图中已经说明了startService的时候,会调用onCreate(),onSstartCommand()方法,然后停止服务的时候我们可以调用stopService()或者stopSelf()方法;如果是bindService的时候,则会调用onCreate(),onBind()方法返回binder对象,然后会回调ServiceConnection
对象,解除绑定的时候可以调用unBindService()来回调onUnbind()方法。和上一篇一样,我们这里就贴一下startService的启动过程概图:
startService流程图
我们看到和Activity启动不一样的是,这里并不是通过Instrumentation
来进行管理创建过程的,而是直接通过ActivityManagerProxy
和AMS
通讯进行创建的。
一.Service管理过程分析
插件化框架VirtualApk在Service的管理上采用了一种称为代理分发的方式。首先会在AndroidManifest.xml
中注册两种代理Service
,这样要启动插件Service
的时候,我们都会启动这个代理Srevice
,然后在onStartCommand()
方法中进行分发执行插件的onStartCommand()
方法。所以我们先来看看这两个代理Service的注册情况:
<!-- Local Service running in main process -->
<service android:name="com.didi.virtualapk.delegate.LocalService" />
<!-- Daemon Service running in child process -->
<service android:name="com.didi.virtualapk.delegate.RemoteService" android:process=":daemon">
<intent-filter>
<action android:name="${applicationId}.intent.ACTION_DAEMON_SERVICE" />
</intent-filter>
</service>
我们看到这里注册了两个代理服务,一个是在主进程中的,一个是在非主进程中的,根据插件服务在的进程进行分别地启动。而且在前面的初始化我们已经看到,一个是hook 了Instrumentation
类还有一个是hook了IActivityManager
,我们来看看:
private void hookSystemServices() {
try {
Singleton<IActivityManager> defaultSingleton = (Singleton<IActivityManager>) ReflectUtil.getField(ActivityManagerNative.class, null, "gDefault");
IActivityManager activityManagerProxy = ActivityManagerProxy.newInstance(this, defaultSingleton.get());
// Hook IActivityManager from ActivityManagerNative
ReflectUtil.setField(defaultSingleton.getClass().getSuperclass(), defaultSingleton, "mInstance", activit