10.4.2 创建并初始化ProcessRecord
接下来分析ActivityManagerService.setSystemProcess的最后一步重要工作:创建并初始化ProcessRecord。创建ProcessRecord的工作由ActivityManagerService的newProcessRecordLocked方法完成,代码如下:
final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
ApplicationInfo info, String customProcess, boolean isolated){
//参数customProcess为system
String proc=customProcess!=null?customProcess:info.processName;
//影响电池状态的信息
BatteryStatsImpl.Uid.Proc ps=null;
BatteryStatsImpl stats=mBatteryStatsService.getActiveStatistics();
int uid=info.uid;
if(isolated){//参数为false
……
}
synchronized(stats){
ps=stats.getProcessStatsLocked(info.uid, proc);
}
return new ProcessRecord(ps, thread, info, proc, uid);
}
newProcessRecordLocked需要接收一个IApplicationThread类型的参数,该参数进而传入ProcessRecord的构造函数用于创建ProcessRecord。下面分两步分析这个过程。
1.ApplicationThread类
newProcessRecordLocked方法接收一个IApplicationThread类型的参数,该参数的值由mSystemThread.getApplicationThread()返回。mSystemThread是ActivityManagerService启动阶段执行ActivityThread.systemMain()时创建的ActivityThread。getApplicationThread方法返回ActivityThread的成员变量mAppThread。mAppThread在创建ActivityThread时,初始化为ApplicationThread对象。那么ApplicationThread是什么?先来分析其类的结构,如图10-5所示。
图 10-5 ApplicationThread类的结构
ActivityThread通过成员变量mAppThread持有ApplicationThread对象的引用,并提供getApplicationThread方法返回该对象的引用。ApplicationThread继承自ApplicationThreadNative, ApplicationThreadNative又继承自Binder并实现了IApplicationThread接口,IApplicationThread接口继承自IInterface,因此这是一个典型的Binder服务接口,在该接口中定义了启动和调度Activity的方法。因此ApplicationThread是一个与Activity调度相关的工具类。
ActivityManagerService位于system_server进程中,如果需要调度位于其他进程的Activity,需要通过Binder机制,因此这里提供了ApplicationThread实现这一功能。
2.ProcessRecord构造函数
ProcessRecord用于表示当前运行进程的详细信息,ProcessRecord的构造函数的代码如下:
ProcessRecord(BatteryStatsImpl.Uid.Proc_batteryStats,
IApplicationThread_thread,
ApplicationInfo_info, String_processName, int_uid){
batteryStats=_batteryStats;//记录电池状态
//保存android包的ApplicationInfo,即第一个运行于此进程的应用程序信息
info=_info;
isolated=_info.uid!=_uid;//false
uid=_uid;//该进程对应的uid
userId=UserId.getUserId(_uid);//该进程对应的userID
processName=_processName;//进程名,其值为system
//运行于该进程的包,一个进程可以对应多个包
pkgList.add(_info.packageName);
thread=_thread;//保存IApplicationThread,跨进程调度Activity
//与进程调度有关的优先级和adj调整值,后续分析
maxAdj=ProcessList.HIDDEN_APP_MAX_ADJ;
hiddenAdj=ProcessList.HIDDEN_APP_MIN_ADJ;
curRawAdj=setRawAdj=-100;
curAdj=setAdj=-100;
persistent=false;//默认为非“常驻进程”
removed=false;
}
以上只是创建进程信息的默认过程,对于system_server进程来讲,其ProcessRecord需要特殊对待,因此在创建ProcessRecord后,需要将persistent修改为true(表示该进程为常驻进程,如果异常退出需要重启),将maxAdj调整为SYSTEM_ADJ;然后将该ProcessRecord存入ActivityManagerService的mProcessNames、mPidsSelfLocked这两个成员变量中;最后调用updateLruProcessLocked调整进程的最近、最少使用列表(LRU)和OOM adj的值,这部分内容后续再分析。
接下来分析系统启动阶段ActivityManagerService第三阶段的工作。