之前已经分析完在同app进程中bindService的过程。今天继续分析在新进程中bindService的流程。之前的分析可以参考juejin.cn/post/710270…
接着第二篇最后的分析 ActiveServices#bringUpServiceLocked 这里面的启动新进程来分析bindService
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
.......
// 进程未启动
if (app == null && !permissionsReviewRequired) {
// step3.3 启动进程
if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) {
return msg;
}
}
return null;
}
通过mAm.startProcessLocked 启动新的进程,创建新进程涉及到Zygote服务,这边暂时不讨论,可以参考老罗的博客,在进程创建之后回调到ActivityThread的main方法。我们从这边开始分析。 ActivityThread#main
public static void main(String[] args) {
Looper.prepareMainLooper();
// 创建ActivityThread
ActivityThread thread = new ActivityThread();
// 调用ActivityThread的attach
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 启动loop
Looper.loop();
}
这边thread.attach(false, startSeq);会告诉ams进程创建成功,将applicationThread给ams。
ActivityThread#attach
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
......
if (!system) {
final IActivityManager mgr = ActivityManager.getService();
try {
// 通知ams进程创建好了
mgr.attachApplication(mAppThread, startSeq);
}
}
......
}
调用ams的attachApplication
ActivityManangerService#attachApplication
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
......
ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
}
// See if the top visible activity is waiting to run in this process...
// 检查是否有activity等待此进程运行
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
}
}
// Find any services that should be running in this process...
// 检查是否有service等待此进程运行
if (!badApp) {
try {
// step1 检查service
didSomething |= mServices.attachApplicationLocked(app, processName);
}
}
......
return true;
}
ams会先调用bindApplication创建application。下面会先检查是否有activity等待此进程运行,然后检查是否有service等待此进程运行,所以activity的优先级比service的高点。
ActiveServices#attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
......
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i = 0; i < mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
// 遍历mPendingServices,查找响应的service
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
// 启动service
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
}
}
......
}
return didSomething;
}
遍历mPendingServices查找对应的ServiceRecord。前面第二篇最后ActiveServices#bringUpServiceLocked juejin.cn/post/710046… 可以看到如果进程未启动servicerecord会保存到mPendingServices中的。 找到后执行realStartServiceLocked方法。 该方法的流程之前已经分析过了,参考juejin.cn/post/710270…