从Launcher启动app的LauncherActivity
Launcher.startActivity或者Context.startActivity【ContextImpl.startActivity 】
都会调用到Instrumentation.execStartActivity
函数定义在frameworks/base/core/java/android/app/Instrumentation.java文件中:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
......
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
if (mActivityMonitors != null) {
......
}
try {
......
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
......
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManager.getService()返回ActivityManagerService的远程接口,通过Binder调用,进入AMS中。
以上是在Launcher进程中
ActivityManagerService.startActivity
函数在\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java文件中:
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
简单调用ActivityManagerService.startActivityAsUser
ActivityManagerService.startActivityAsUser
函数在\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java文件中
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
简单地将操作转发给成员变量mActivityStarter的startActivityMayWait函数,这里的mActivityStarter的类型为com.android.server.am.ActivityStarter
ActivityStarter.startActivityMayWait
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
ActivityStarter.startActivityLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
简单调用ActivityStarter.startActivity
ActivityStarter.startActivity
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
一堆检查操作后,直接调用ActivityStarter.startActivity
ActivityStarter.startActivity
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
直接调用ActivityStarter.startActivityUnchecked
ActivityStarter.startActivityUnchecked
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
这里检查了权限、任务栈、启动模式
ActivityStarter.setTargetStackAndMoveToFrontIfNeeded
\frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
/**
* Figure out which task and activity to bring to front when we have found an existing matching
* activity record in history. May also clear the task if needed.
* @param intentActivity Existing matching activity.
* @return {@link ActivityRecord} brought to front.
*/
注释翻译:在我们找到历史记录中的现有匹配活动记录时,确定要将哪些任务和活动带到前面。 如果需要,也可以清除任务 。
intentActivity.showStartingWindow显示一个starting window
ActivityStack.moveTaskToFrontLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java
ActivityStack.resumeTopActivityUncheckedLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
ActivityStack.resumeTopActivityInnerLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
......
final boolean userLeaving = mStackSupervisor.mUserLeaving;
......
final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0 && !lastResumedCanPip;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, next, false);
}
if (pausing && !resumeWhilePausing) {
......
return true;
} else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
......
return true;
}
......
if (prev != null && prev != next) {
......
}
......
boolean anim = true;
if (prev != null) {
......
} else {
......
}
......
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
......
setResumedActivityLocked(next, "resumeTopActivityInnerLocked");
......
boolean notUpdated = true;
if (mStackSupervisor.isFocusedStack(this)) {
......
notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next, false /* deferResume */, mDisplayId);
}
if (notUpdated) {
.....
ActivityRecord nextNext = topRunningActivityLocked();
......
if (nextNext != next) {
// Do over!
mStackSupervisor.scheduleResumeTopActivities();
}
if (!next.visible || next.stopped) {
next.setVisibility(true);
}
next.completeResumeLocked();
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
try {
......
if (next.newIntents != null) {
next.app.thread.scheduleNewIntent(
next.newIntents, next.appToken, false /* andPause */);
}
......
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
mService.isNextTransitionForward(), resumeAnimOptions);
......
} catch (Exception e) {
......
return true;
}
// From this point on, if something goes wrong there is no way
// to recover the activity.
try {
next.completeResumeLocked();
} catch (Exception e) {
......
return true;
}
} else {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
此处调用mStackSupervisor.pauseBackStacks一直等着结果回来以后,继续向下执行,这个结果是pausing =true。ActivityStackSupervisor.pauseBackStacks又调用ActivityStack.startPausingLocked里面会将mResumedActivity置为null,所以pausing |= startPausingLocked(userLeaving, false, next, false)不会执行到。resumeTopActivityInnerLocked第一次调用的时候,pausing && !resumeWhilePausing = true,所以,当在if (pausing && !resumeWhilePausing)代码块中直接return true了,后面代码不会执行。
startPausingLocked最终会调用到completePauseLocked,而completePauseLocked最终又会间接调用到resumeTopActivityInnerLocked。通过completePauseLocked最终间接调用到resumeTopActivityInnerLocked的时候,会调用到mStackSupervisor.startSpecificActivityLocked(next, true, true)。也就是这个过程中,此时resumeTopActivityInnerLocked已经调用了两次了.
ActivityStackSupervisor.pauseBackStacks
\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack) && stack.mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
" mResumedActivity=" + stack.mResumedActivity);
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
dontWait);
}
}
}
return someActivityPaused;
}
此处调用stack.startPausingLocked,返回someActivityPaused=true
ActivityStack.startPausingLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
......
ActivityRecord prev = mResumedActivity;
......
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.state = ActivityState.PAUSING;
prev.getTask().touchActiveTime();
clearLaunchTime(prev);
......
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
......
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, pauseImmediately);
} catch (Exception e) {
......
}
} else {
......
}
......
if (mPausingActivity != null) {
......
if (pauseImmediately) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false, resuming);
return false;
} else {
schedulePauseTimeout(prev);
return true;
}
} else {
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (resuming == null) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
return false;
}
}
prev.app.thread.schedulePauseActivity通过ApplicationThread调用android.app.ActivityThread.H发送Handler消息在Launcher进程的主线程中调用handlePauseActivity。
从上面调用得知pauseImmediately=false,会调用schedulePauseTimeout(prev),
pause超时后,发送handler消息立刻执行ActivityStack.activityPausedLocked。
ActivityThread.handlePauseActivity
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
......
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb(), handlePauseActivity");
......
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
ActivityManager.getService().activityPaused(token),此处调用AMS的activityPaused
ActivityManagerService.activityPaused
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
此处调用ActivityStack.activityPausedLocked
ActivityStack.activityPausedLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
final void activityPausedLocked(IBinder token, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Activity paused: token=" + token + ", timeout=" + timeout);
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
......
try {
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
return;
} else {
......
}
}
......
}
此处调用ActivityStack.completePauseLocked
ActivityStack.completePauseLocked
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
......
mPausingActivity = null;
}
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecord top = topStack.topRunningActivityLocked();
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run, do resume anyway to start
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
}
if (prev != null) {
......
}
......
}
这里调用了mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);最终由调用到ActivityStack.resumeTopActivityInnerLocked,然后继而调用mStackSupervisor.startSpecificActivityLocked(next, true, true);**这一轮调用不是刚开始15那轮调用,此时15那轮调用还没结束呢!**一直等pause的全部逻辑结束后,ActivityStack.resumeTopActivityInnerLocked的第一轮调用中才到if (pausing && !resumeWhilePausing)中return true;
22. ActivityStackSupervisor.startSpecificActivityLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java
```java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
```
app启动,所以if代码块不会执行到。
ActivityManagerService.startProcessLocked
函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
此处hostingType = “activity”
ActivityManagerService.startProcessLocked
函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
......
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
......
return (app.pid != 0) ? app : null;
}
此处hostingType = “activity”
ActivityManagerService.startProcessLocked
函数在\frameworks\base\services\core\java\com\android\server\am\startProcessLocked.java文件中:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
try {
......
String invokeWith = null;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// Debuggable apps may include a wrapper script with their library directory.
String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
if (new File(wrapperFileName).exists()) {
invokeWith = "/system/bin/logwrapper " + wrapperFileName;
}
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}
......
ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
......
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
......
} catch (RuntimeException e) {
......
}
}
此处hostingType = “activity”。invokeWith = null。
Process.start
\frameworks\base\core\java\android\os\Process.java
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
这里的processClass就是要启动的app的ActivityThread,最终会找到ActivityThread.main;
invokeWith = null.
ZygoteProcess.start
\frameworks\base\core\java\android\os\ZygoteProcess.java
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
......
}
}
这里的processClass就是要启动的app的ActivityThread,最终会找到ActivityThread.main
invokeWith = null.
ZygoteProcess.startViaZygote
\frameworks\base\core\java\android\os\ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
............
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
把zygote进程fork子进程所需要的参数放入argsForZygote
ZygoteProcess.zygoteSendArgsAndGetResult
\frameworks\base\core\java\android\os\ZygoteProcess.java
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
......
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);
}
}
通过socket和zygote进程通信,用BufferedWriter把参数写入socket传递给zygote进程,最后通过DataInputStream把zygote进程fork子进程的结果读出来.
3~~29是在AMS即system_server进程
ZygoteInit.main
\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
......
final Runnable caller;
try {
......
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
Zygote进程是在系统启动后就被启动的进程,初始化在ZygoteInit.main中完成,ygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,这里会取出ams发送来的参数,fork一个子进程,此处即app进程
ZygoteServer.runSelectLoop
\frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This shows up as
// a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
......
} else {
// We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other main()
// method). Log the details of the exception and bring down the process.
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
}
}
}
}
}
zygote进程通过ZygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,
划重点:final Runnable command = connection.processOneCommand(this);
ZygoteConnection.processOneCommand
\frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
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);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
//void setForkChild() {
// mIsForkChild = true;
//}
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
Zygote.forkAndSpecialize刚刚fork出来的子进程会完全继承父进程的所有状态,包括运行时、文件、资源等,所以子进程也有while循环,也会在main方法里没出来;
pid == 0是子进程,zygoteServer.setForkChild()标记为子进程,通过ZygoteConnectionhandleChildProc返回一个Runnable,这样就跳出while循环,并且把runnable return出去,在ZygoteInit.main中赋给了caller,caller调用run方法,最终调用到ActivityThread.main
,这个runnable由ZygoteInit.zygoteInit调用RuntimeInit.applicationInit创建
补充:
linux创建子进程–fork()方法
https://www.cnblogs.com/xingzc/p/5988069.html
(1)fork()的定义
fork()函数是Unix中派生新进程的唯一方法,声明如下:
我们需要理解的是,调用一次fork()方法,该方法会返回两次。一次是在调用进程(也就是派生出的子进程的父进程)中返回一次,返回值是新派生的进程的进程ID。一次是在子进程中返回,返回值是0,代表当前进程为子进程。如果返回值为-1的话,则代表在派生新进程的过程中出错。
那么在程序中,我们就可以根据此返回值来判断当前进程是父进程还是子进程,来实现一些具体的操作。
(2)fork()的实质过程
父进程中在调用fork()派生新进程,实际上相当于创建了进程的一个拷贝;即在fork()之前的进程拥有的资源会被复制到新的进程中去。网络服务器在处理并发请求时,也可以采取这种派生新进程的方式: 父进程调用accept()后调用fork()来处理每一个连接。那么,所接受的已连接的套接口随后就在父子进程中共享。通常来说,子进程会在这连接套接口中读和写操作,父进程则关闭这个已连的套接口(可以参考:http://blog.csdn.net/moxiaomomo/article/details/6791763)
(3)fork()的用法
fork()有两个典型用法:(1)一个进程进行自身的复制,这样每个副本可以独立的完成具体的操作,在多核处理器中可以并行处理数据。这也是网络服务器的其中一个典型用途,多进程处理多连接请求。 (2)一个进程想执行另一个程序。比如一个软件包含了两个程序,主程序想调起另一个程序的话,它就可以先调用fork来创建一个自身的拷贝,然后通过exec函数来替换成将要运行的新程序。
ZygoteConnectionhandleChildProc
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd) {
.......
if (parsedArgs.invokeWith != null) {
......
} else {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);
}
}
从20,21可知,parsedArgs.invokeWith = null
ZygoteInit.zygoteInit
\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
......
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
String[] argv里面就是ActivityThread.main相关信息
RuntimeInit.applicationInit
\frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
......
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
方法名很直观,应用初始化
RuntimeInit.findStaticMain
\frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
这里就找到了app进程的ActivityThread.main,最终在ZygoteInit.main中调用.
ActivityThread.main
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("" );
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
ActivityThread.main中在启动主消息循环之前,创建了一个ActivityThread对象并调用attach方法,ActivityThread对象创建的时候,ActivityThread对象的成员变量ApplicationThread 对象立刻创建final ApplicationThread mAppThread = new ApplicationThread();。
ActivityThread.attach
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
......
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
......
} else {
......
}
......
}
将app进程的ApplicationThread对象mAppThread绑定到AMS
ActivityManagerService.attachApplication
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
......
attachApplicationLocked(thread, callingPid);
......
}
}
ActivityManagerService.attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
try {
......
if (app.instr != null) {
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);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
}
......
} catch (Exception e) {
......
return false;
}
......
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
return true;
}
AMS通过Binder对象即ApplicationThread对象thread,调用.ActivityThread.ApplicationThread.bindApplication,紧接着调用mStackSupervisor.attachApplicationLocked(app),ActivityStackSupervisor.attachApplicationLocked里面调用了ActivityStackSupervisor.realStartActivityLocked
ActivityThread.ApplicationThread.bindApplication
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
String buildSerial) {
......
sendMessage(H.BIND_APPLICATION, data);
}
case BIND_APPLICATION:里调用handleBindApplication
ActivityThread.handleBindApplication
private void handleBindApplication(AppBindData data) {
......
final InstrumentationInfo ii;
......
// Continue loading instrumentation.
if (ii != null) {
......
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
......
}
......
} else {
mInstrumentation = new Instrumentation();
}
......
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
......
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
......
}
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
......
}
初始化ActivityThread成员变量mInstrumentation;创建Application对象,并回调Application的onCreate,其实attachBaseContext在makeAppliaction就调用了.
LoadedApk.makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
.......
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
......
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
.......
}
m......
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
......
return app;
}
如果Application对象已经创建,则直接返回;如果没有创建,则交由ActivityThread的成员变量mInstrumentation的方法newApplication创建;传过来的参数instrumentation=null,所以此处不会调用onCreate
Instrumentation.newApplication
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
Application.attach
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
Application.attach里调用attachBaseContext(context);所以看出比onCreate执行的时机早。这些都是在ActivityThread的主消息循环中执行的。
接下来回到AMS中的attachApplicationLocked中调用的mStackSupervisor.attachApplicationLocked(app)
ActivityStackSupervisor.attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked();
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
......
throw e;
}
}
}
}
}
......
return didSomething;
}
这里调用了realStartActivityLocked
ActivityStackSupervisor.realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
......
final ActivityStack stack = task.getStack();
try {
if (app.thread == null) {
throw new RemoteException();
}
......
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global and
// override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
......
} catch (RemoteException e) {
......
throw e;
}
......
return true;
}
这里通过AppliactionThread调用ActivityThread.ApplicationThread.scheduleLaunchActivity,通过ActivityThread.H调用到handleLaunchActivity
ActivityThread.handleLaunchActivity
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
.......
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
......
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
......
} else {
......
}
}
ActivityThread.performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
......
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
......
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
......
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
......
}
return activity;
}
通过反射创建Activity对象,创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到Activity中去,通过mInstrumentation的callActivityOnCreate调用Activity.onCreate,LauncherActivity就启动起来了,整个应用程序也启动起来了,但是此时还不可见。ActivityThread.handleLaunchActivity中还调用了handleResumeActivity
ActivityThread.handleResumeActivity
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
......
r = performResumeActivity(token, clearHide, reason);
if (r != null) {
final Activity a = r.activity;
......
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
......
}
}
......
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
......
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
......
} else {
......
}
}
这里调用了performResumeActivity 和activity.makeVisible()
makeVisible之后,Activity才真正可见并且可交互。
Activity.makeVisible
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
Android应用程序启动过程源代码分析