2,进程管理
其实,android系统所说的进程管理,就是对四大组件的管理,因为其他的类基本是一些普通的类。
当然, droidplugin框架中的进程管理,也是四大组件的管理。Android 系统中的进程管理在此就不论述了。
进程管理的结构图如下,
这些类的构造方法在此就不论述了,都比较简单。
PluginManager是客户端,对应的服务端是IpluginManagerImpl,其实就是模仿android系统的PackageManagerService,
提供对插件简单的管理服务。
一般调用PluginManager的方法时,也就是直接调用IpluginManagerImpl的对应方法。
有的方法调用MyActivityManagerService实现。
ProcessItem是RunningProcesList的内部类,主要是保存一些组件相关的信息。
2.1 activity
还是ActivityThread 的performLaunchActivity方法,在加载完成Activity之后,会调用mInstrumentation的callActivityOnCreate方法,
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
当然,在acitivity的生命周期中,还会调用类似的其他方法,
mInstrumentation.callActivityOnDestroy(r.activity);
当然,有些方法PluginInstrumentation也实现了,相当于自己来管理activity的生命周期。
2.1.1 创建
PluginInstrumentation的callActivityOnCreate方法调用流程图如下,
callActivityOnCreate方法的部分代码如下,
onActivityCreated(activity);
onActivityCreated方法主要逻辑如下,
1,获取替换(宿主)和真实(插件)的ActivityInfo,
Intent targetIntent = activity.getIntent();
if (targetIntent != null) {
ActivityInfo targetInfo = targetIntent.getParcelableExtra(Env.EXTRA_TARGET_INFO);
ActivityInfo stubInfo = targetIntent.getParcelableExtra(Env.EXTRA_STUB_INFO);
2,调用RunningActivities的onActivtyCreate方法,
RunningActivities.onActivtyCreate(activity, targetInfo, stubInfo);
3,调用PluginManager的onActivityCreated方法,
PluginManager.getInstance().onActivityCreated(stubInfo, targetInfo);
RunningActivities的onActivtyCreate方法如下,
public static void onActivtyCreate(Activity activity, ActivityInfo targetActivityInfo, ActivityInfo stubActivityInfo) {
synchronized (mRunningActivityList) {
RunningActivityRecord value = new RunningActivityRecord(activity, targetActivityInfo, stubActivityInfo, findMaxIndex() + 1);
mRunningActivityList.put(activity, value);
if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
mRunningSingleStandardActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
mRunningSingleTopActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
mRunningSingleTaskActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
mRunningSingleInstanceActivityList.put(value.index, value);
}
}
}
创建RunningActivityRecord对象, RunningActivityRecord是RunningActivities的内部类,主要是记录一对宿主和插件activity的信息,
然后根据activity的启动模式分别放入不同的哈希表中,
private static Map<Activity, RunningActivityRecord> mRunningActivityList = new HashMap<>();
private static Map<Integer, RunningActivityRecord> mRunningSingleStandardActivityList = new HashMap<>();
private static Map<Integer, RunningActivityRecord> mRunningSingleTopActivityList = new HashMap<>();
private static Map<Integer, RunningActivityRecord> mRunningSingleTaskActivityList = new HashMap<>();
private static Map<Integer, RunningActivityRecord> mRunningSingleInstanceActivityList = new HashMap<>();
mRunningActivityList记录了所有的已启动的activity,其他四个变量记载了对应的启动模式的activity。
调用PluginManager的onActivityCreated方法,直接看IpluginManagerImpl的onActivityCreated方法,
public void onActivityCreated(ActivityInfo stubInfo, ActivityInfo targetInfo) throws RemoteException {
mActivityManagerService.onActivityCreated(Binder.getCallingPid(), Binder.getCallingUid(), stubInfo, targetInfo);
}
首先获取组件所在进程的pid和uid,然后调用MyActivityManagerService的onActivityCreated方法,
public void onActivityCreated(int callingPid, int callingUid, ActivityInfo stubInfo, ActivityInfo targetInfo) {
mRunningProcessList.addActivityInfo(callingPid, callingUid, stubInfo, targetInfo);
}
直接调用RunningProcessList的addActivityInfo方法,如下,
void addActivityInfo(int pid, int uid, ActivityInfo stubInfo, ActivityInfo targetInfo) {
ProcessItem item = items.get(pid);
if (TextUtils.isEmpty(targetInfo.processName)) {
targetInfo.processName = targetInfo.packageName;
}
if (item == null) {
item = new ProcessItem();//构造ProcessItem对象
item.pid = pid;//进id
item.uid = uid;//用户id
items.put(pid, item);
}
item.stubProcessName = stubInfo.processName;
if (!item.pkgs.contains(targetInfo.packageName)) {
item.pkgs.add(targetInfo.packageName);
}
item.targetProcessName = targetInfo.processName;
item.addActivityInfo(stubInfo.name, targetInfo);
}
主要就是构造一个内部类ProcessItem对象,然后给变量赋值,其实一个进程id对应一个ProcessItem对象。
然后将ProcessItem对象放入items哈希表中。这样,不同组件的id如果相同,就可以对应一个ProcessItem对象,不用每次都创建。
最后调用ProcessItem的addActivityInfo方法,如下,
private void addActivityInfo(String stubActivityName, ActivityInfo info) {
if (!targetActivityInfos.containsKey(info.name)) {
targetActivityInfos.put(info.name, info);
}
//pkgs
if (!pkgs.contains(info.packageName)) {
pkgs.add(info.packageName);
}
//stub map to activity info
Set<ActivityInfo> list = activityInfosMap.get(stubActivityName);
if (list == null) {
list = new TreeSet<ActivityInfo>(sComponentInfoComparator);
list.add(info);
activityInfosMap.put(stubActivityName, list);
} else {
list.add(info);
}
}
都是将信息添加到哈希表中。ProcessItem 的7个哈希表如下,
1,插件的四大组件对应的包名,一般一个插件对应一个包名。
private List<String> pkgs = new ArrayList<String>(1);
2,正在运行的插件ActivityInfo
//key=ActivityInfo.name, value=插件的ActivityInfo,
private Map<String, ActivityInfo> targetActivityInfos = new HashMap<String, ActivityInfo>(4);
3,正在运行的插件ProviderInfo
//key=ProviderInfo.authority, value=插件的ProviderInfo
private Map<String, ProviderInfo> targetProviderInfos = new HashMap<String, ProviderInfo>(1);
4,正在运行的插件ServiceInfo
//key=ServiceInfo.name, value=插件的ServiceInfo
private Map<String, ServiceInfo> targetServiceInfos = new HashMap<String, ServiceInfo>(1);
5,正在运行的插件ActivityInfo与代理ActivityInfo的映射
//key=代理ActivityInfo.name, value=插件的ActivityInfo.name,
private Map<String, Set<ActivityInfo>> activityInfosMap = new HashMap<String, Set<ActivityInfo>>(4);
6, 正在运行的插件ProviderInfo与代理ProviderInfo的映射
//key=代理ProviderInfo.authority, value=插件的ProviderInfo.authority,
private Map<String, Set<ProviderInfo>> providerInfosMap = new HashMap<String, Set<ProviderInfo>>(4);
7, 正在运行的插件ServiceInfo与代理ServiceInfo的映射
//key=代理ServiceInfo.name, value=插件的ServiceInfo.name,
private Map<String, Set<ServiceInfo>> serviceInfosMap = new HashMap<String, Set<ServiceInfo>>(4);
可以看到的是并没有广播的相关哈希表,因为广播直接有系统进行管理。
2.1.2 OnDestroy
PluginInstrumentation的callActivityOnDestroy方法如下,
public void callActivityOnDestroy(Activity activity) {
if (mTarget != null) {
mTarget.callActivityOnDestroy(activity);
} else {
super.callActivityOnDestroy(activity);
}
RunningActivities.onActivtyDestory(activity);
if (enable) {
try {
onActivityDestory(activity);
} catch (RemoteException e) {
Log.e(TAG, "callActivityOnDestroy:onActivityDestory", e);
}
}
}
首先调用RunningActivities的onActivtyDestory方法,该方法和onActivtyCreate
public static void onActivtyDestory(Activity activity) {
synchronized (mRunningActivityList) {
RunningActivityRecord value = mRunningActivityList.remove(activity);
if (value != null) {
ActivityInfo targetActivityInfo = value.targetActivityInfo;
if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
mRunningSingleStandardActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
mRunningSingleTopActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
mRunningSingleTaskActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
mRunningSingleInstanceActivityList.remove(value.index);
}
}
}
}
onActivityDestory方法如下,
private void onActivityDestory(Activity activity) throws RemoteException {
Intent targetIntent = activity.getIntent();
if (targetIntent != null) {
ActivityInfo targetInfo = targetIntent.getParcelableExtra(Env.EXTRA_TARGET_INFO);
ActivityInfo stubInfo = targetIntent.getParcelableExtra(Env.EXTRA_STUB_INFO);
if (targetInfo != null && stubInfo != null) {
PluginManager.getInstance().onActivityDestory(stubInfo, targetInfo);
}
}
}
和onActivityCreated的调用流程完全一样。调用流程图如下,
MyActivityManagerService的onActivityDestory方法如下,
public void onActivityDestory(int callingPid, int callingUid, ActivityInfo stubInfo, ActivityInfo targetInfo) {
mRunningProcessList.removeActivityInfo(callingPid, callingUid, stubInfo, targetInfo);
runProcessGC();
}
ProcessItem的removeActivityInfo方法和addActivityInfo方法完全相反,就是在哈希表中删除元素的过程,
void removeActivityInfo(String stubActivityName, ActivityInfo targetInfo) {
targetActivityInfos.remove(targetInfo.name);
//remove form map
if (stubActivityName == null) {
for (Set<ActivityInfo> set : activityInfosMap.values()) {
set.remove(targetInfo);
}
} else {
Set<ActivityInfo> list = activityInfosMap.get(stubActivityName);
if (list != null) {
list.remove(targetInfo);
}
}
updatePkgs();
}
runProcessGC 方法主要进行进程垃圾回收。放在后面论述.