4,Service Hook解析
Service/ContentProvider由于没有Activity那么复杂的启动过程,并且Activity的生命周期是由用户交互决定的,
而Service的声明周期是主动通过代码调用的。因此虽然也有替换/还原过程,但是有点不同,是采用代理分发技术。
就是启动宿主的Service/ContentProvider对象,然后管理插件的Service/ContentProvider对象。
Service 的Hook 是通过ActivityManagerProxy完成的。
ActivityManagerProxy类Hook了ActivityManager的7个方法,其中和service相关的有5个,分别是startService/ stopService/
stopServiceToken/bindService/ unbindService,这5个方法主要和service的生命周期有关。并且所有方法的调用流程
完全相同,因此,以startService方法为例来论述。
在AndroidManifest中注册了两类service,一类LocalService,多进程时为RemoteService,
<!-- 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>
ActivityManagerProxy的invoke方法中有关startService处理的代码如下,
if ("startService".equals(method.getName())) {
try {
return startService(proxy, method, args);
startService方法如下,
private Object startService(Object proxy, Method method, Object[] args) throws Throwable {
IApplicationThread appThread = (IApplicationThread) args[0];
Intent target = (Intent) args[1];
ResolveInfo resolveInfo = this.mPluginManager.resolveService(target, 0);
if (null == resolveInfo || null == resolveInfo.serviceInfo) {
// is host service
return method.invoke(this.mActivityManager, args);
}
return startDelegateServiceForTarget(target, resolveInfo.serviceInfo, null, RemoteService.EXTRA_COMMAND_START_SERVICE);
}
首先调用PluginManager的resolveService方法匹配出目标intent的相关信息,然后调用startDelegateServiceForTarget方法进行替换.
4.1 匹配
PluginManager的reso