赞
踩
从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
mSupervisor.resolveActivity解析出ActivityInfo aInfo后,调用startActivityLocked
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
这里检查了权限、任务栈、启动模式
(如果是从桌面冷启动APP,那么会因为getReusableIntentActivity方法返回的reusedActivity是null,则不执行10和11。调用 ActivityStack 的 startActivityLocked 方法 mTargetStack.startActivityLocked,此处将启动的 Activity 插入到栈顶部并showStartingWindow显示一个starting window;继续调用mSupervisor.resumeFocusedStackTopActivityLocked)显示栈顶元素(参考自:https://blog.csdn.net/shulianghan/article/details/120249208)
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
11. 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,这一次调用到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;
ActivityStack.resumeTopActivityInnerLocked两次调用的调用栈如下:
22. ActivityStackSupervisor.startSpecificActivityLocked
\frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.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); } } ...... if (entryPoint == null) entryPoint = "android.app.ActivityThread"; ...... 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中完成,zygoteServer.runSelectLoop启动一个死循环,就是为了fork进程,这里会取出ams发送来的参数,fork一个子进程,此处即app进程。
如果是子进程,会执行caller.run()。原因后续分析。
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()标记为子进程,即把当前进程的mIsForkChild设置为true;由Zygote进程创建的子进程会继承Zygote进程中创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket方法来关闭它,再通过ZygoteConnection.handleChildProc返回一个Runnable,因为mIsForkChild为true,这样新的子进程就跳出while循环,并且把刚刚的runnable return出去,在ZygoteInit.main中赋给caller,caller调用run方法,最终调用到ActivityThread.main
,这个runnable由ZygoteInit.zygoteInit调用RuntimeInit.applicationInit创建
补充:
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函数来替换成将要运行的新程序。
ZygoteConnection.handleChildProc
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) {
......
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
调用zygoteInitNative方法来执行一个Binder进程间通信机制的初始化工作:打开Binder驱动,mmap映射,启动Binder线程池(此时启动一个Binder主线程)。这个过程参考进程的Binder线程池工作过程
String[] argv里面就是ActivityThread.main相关信息,将这些信息参数封装进一个Runnable里。
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("<pre-initialized>"); 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;通过LoadedApk.makeApplication创建Application对象,然后回调Application的onCreate,注意:Application的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.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);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。