ps:Android 27
本文从桌面图标点击
开始,到ActivityThread#main
结束
桌面Activity
- android.app.LauncherActivity
这是一个ListActivity,主要负责呈现手机主屏幕的桌面图标。
// ListView的Item点击事件
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = intentForPosition(position);
startActivity(intent);
}
- 调用
Activity#startActivity(Intent intent)
- 调用
Activity#startActivity(Intent intent, Bundle options)
- 调用
Activity#startActivityForResult(Intent intent, int requestCode,Bundle options)
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
// 这步其实没看懂,等看懂了再回来补充吧
// 但最终都是会走到mInstrumentation#execStartActivity
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
- 调到
Instrumentation#execStartActivity
public ActivityResult execStartActivity() {
// ActivityThread的重要IBinder对象,负责跨进程通信
IApplicationThread whoThread = (IApplicationThread) contextThread;
....
try {
....
// 调用AMS的startActivity,whoThread = 跨进程通信Binder
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
那就进一步往下看吧,看看AMS的startActivity
做了什么!
- 调到
ActivityManagerService#startActivity
- 调到
ActivityManagerService#startActivityAsUser
在这个方法内调到了ActivityStarter内的启动逻辑 - 调到
ActivityStarter#startActivityMayWait
final int startActivityMayWait() {
....
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
....
return res;
}
- 调到
ActivityStarter#startActivityLocked
int startActivityLocked() {
...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask);
...
return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}
- 调到
ActivityStarter #startActivity(22 参)
- 调到
ActivityStarter #startActivity(9 参)
private int startActivity(9 参) {
int result = START_CANCELED;
try {
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
...
}
...
return result;
}
- 调到
ActivityStarter #startActivityUnchecked()
private int startActivityUnchecked(){
....
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
....
}
- 调到
ActivityStack#startActivityLocked()
final void startActivityLocked() {
....
// 这种情况下,先不要启动Window
if (r.mLaunchTaskBehind) {
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
r.setVisibility(true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
} ...
}
- 调用
ActivityStack#ensureActivitiesVisibleLocked
final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,boolean preserveWindows) {
..........
// ProcessRecord 或者 ProcessRecord的IApplicationThread 空时
if (r.app == null || r.app.thread == null) {
if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,resumeNextActivity, r)) {
....
}
}
..........
}
- 调用
ActivityStack#makeVisibleAndRestartIfNeeded
private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
boolean isTop, boolean andResume, ActivityRecord r) {
// We need to make sure the app is running if it's the top, or it is just made visible from
// invisible. If the app is already visible, it must have died while it was visible. In this
// case, we'll show the dead window but will not restart the app. Otherwise we could end up
// thrashing.
if (isTop || !r.visible) {
// This activity needs to be visible, but isn't even running...
// get it started and resume if no other stack in this stack is resumed.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
if (r != starting) {
r.startFreezingScreenLocked(r.app, configChanges);
}
if (!r.visible || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
r.setVisible(true);
}
if (r != starting) {
mStackSupervisor.startSpecificActivityLocked(r, andResume, false);
return true;
}
}
return false;
}
- 调到
ActivityStackSupervisor#startSpecificActivityLocked
void startSpecificActivityLocked() {
// 如果进程已经创建的逻辑
...
// 如果没创建进程,则开始创建进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);
}
- 调到
ActivityManagerService#startProcessLocked(9 参)
- 调到
ActivityManagerService#startProcessLocked(14 参)
- 调到
ActivityManagerService#startProcessLocked(6 参)
private final void startProcessLocked(6参){
....
// 注意看这里,ActivityThread类路径被当做参数传递到Process,最终会被放置到args[]中,
// 在fork进程的请求中通过socket带到Zygote进程,下面我们分析runSelectLoop() 方法时就会恍然大悟
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, entryPointArgs);
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
.....
}
- 调用
Process#start
- 调用
ZygoteProcess#start
- 调用
ZygoteProcess#startViaZygote
- 调用
ZygoteProcess.zygoteSendArgsAndGetResult [static method]
这里走的是socket通信,具体原因我还不太懂,等后续再补充吧。
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult() {
try {
...
// socket 通信
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
至此,Zygote进程已经fork出一个全新的进程
在socket通信的过程中,ActivityThread.main 的启动作为一个参数被传递给Zygote进程,fork结束后,会默认调用ActivityThread#main (分析runSelectLoop的时候细看)(这是Android 27内的处理逻辑,其他版本有些差异,但整体流程大同小异)
顺便看看ActivityThread的启动
上面我们提到SystemServer进程
中,ZygoteProcess#zygoteSendArgsAndGetResult方法里通过Socket将启动消息发到了Zygote进程
。被ZygoteServer#runSelectLoop方法注册的消息处理器获取并处理。
- ZygoteServer#runSelectLoop
Runnable runSelectLoop(String abiList) {
...
// 其他的就不看了
while (true) {
final Runnable command = connection.processOneCommand(this);
return command;
}
}
- ZygoteConnection.processOneCommand
Runnable processOneCommand(ZygoteServer zygoteServer) {
// 创建进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
if (pid == 0) {
return handleChildProc(parsedArgs, descriptors, childPipeFd);
} else {
return null;
}
}
- ZygoteConnection.handleChildProc
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd){
// 看到这里就熟悉了吧,返回一个ActivityThread的启动器
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /*classLoader */);
}