App启动流程分析(上)

xiaoxiao2021-02-28  71

App启动流程分析

一.概述流程

在LAUNCH界面,点击一个app的图标之后,会调用startActivity来启动对应的Activity。

通过Binder远程通知AMS启动新的Activity。

AMS进行一系列的权限判断,创建ActivityRecord记录信息,Activity栈处理….等等一系列处理,最后会调用到startSpecificActivityLocked方法中。startSpecificActivityLocked方法中会进行判断,在进程没有启动的情况下,会调用startProcessLocked=>startProcessLocked=>Process.start()来启动一个进程。Process.start()是一个静态方法,他作为客户端会通过sockt与zygote进行通讯,Zygote作为服务端。Zygote通过JNI调用native方法fork一个它的子进程,并返回进程的pid。调用zygoteConnection的handleChildProc方法。关闭socoket,进行一些进程的设置,默认未捕捉异常的处理方法、时区的设置、重置log的配置,binder线程池和线程创建….通过反射来调用到ActivityThread的main方法,main方法中创建主线程Looper、并调用attach方法。通过Binder通讯调用AMS的attachApplicationLocked()方法,启动主线程Looper循环。跨进程调用ApplicationThread的bindApplication方法,通过Handler发送消息调用到ActivityThread的handleBindApplication方法,在这个方法中会完成创建Context的实现类ContextImpl对象、初始化Intrumentation对象、创建Application对象、装载Provider、调用Application的onCreate方法。调用到realStartActivityLocked,然后跨进程调用到applicationThread的scheduleLaunchActivity方法,scheduleLaunchActivity就会正真创建Activity。

二.具体流程分析

一 . 远程调用AMS中StartActivity

1.1 StartActivity

在Android中,当我们启动一个新的Activity或者service时,都是直接在Activity中调用StartActivity或者startService方法。这个方法最终会调用到startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); //调用Instrumentation中的execStartActivity方法 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()); } //requestCode为-1 if (requestCode >= 0) { mStartedActivity = true; } cancelInputsAndStartExitTransition(options); } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } } }

其中:mMainThread的数据类型是ActivityThread,其中mMainThread.getApplicationThread()方法得到ApplicationThread;

1.2 execStartActivity

public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) { am.mHits++; //如果阻塞,直接return if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } } } } try { intent.setAllowFds(false); //获得ActivityManagerProxy对象,调用startActivity int result = ActivityManagerNative.getDefault() .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token, target != null ? target.mEmbeddedID : null, requestCode, false, false, null, null, false); //检查Activity是否启动成功 checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null; } }

其中ActivityManagerNative.getDefault()会获得ActivityManagerService的本地代理对象ActivityManagerProxy, 调用ActivityManagerProxy.startActivity会通过Binder跨进程调用AMS中的startActivity方法;

二 Binder远程调用

2.1 ActivityManagerNative.getDefault().startActivity

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; String profileFile = data.readString(); ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null; boolean autoStopProfiler = data.readInt() != 0; //远程调用AMS中的startActivity int result = startActivity(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler); reply.writeNoException(); reply.writeInt(result); return true; }

三 AMS中具体启动流程

3.1 AMS.startActivity()

public final int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { //直接调用了ActivityStack中的startActivityMayWait return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler, null, null); }

3.2 ActivityStack.startActivityMayWait()

直接调用了ActivityStack中的方法

final int startActivityMayWait(IApplicationThread caller, int callingUid, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler, WaitResult outResult, Configuration config) { ... intent = new Intent(intent); // 根据传入的Intent收集要启动的目标Activity的信息 ActivityInfo aInfo = resolveActivity(intent, resolvedType, debug, profileFile, profileFd, autoStopProfiler); ... ActivityContainer container = (ActivityContainer)iContainer; synchronized (mService) { //见3.3小结 int res = startActivityLocked(caller, intent, resolvedType, grantedUriPermissions, grantedMode, aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, onlyIfNeeded, componentSpecified, null); ... return res; } }

3.3 ActivityStack.startActivityLocked()

final int startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, boolean onlyIfNeeded, boolean componentSpecified, ActivityRecord[] outActivity) { int err = START_SUCCESS; //调用者进程记录对象 ProcessRecord callerApp = null; //判断调用者本身进程的存在,否则记录START_PERMISSION_DENIED,并在后面return if (caller != null) { callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null) { callingPid = callerApp.pid; callingUid = callerApp.info.uid; } else { Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid + ") when starting: " + intent.toString()); err = START_PERMISSION_DENIED; } } if (err == START_SUCCESS) { Slog.i(TAG, "START {" + intent.toShortString(true, true, true) + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); } //调用者Activity的Activity信息记录对象 ActivityRecord sourceRecord = null; //要启动的Activity的Activity信息记录对象 ActivityRecord resultRecord = null; if (resultTo != null) { int index = indexOfTokenLocked(resultTo); if (DEBUG_RESULTS) Slog.v( TAG, "Will send result to " + resultTo + " (index " + index + ")"); if (index >= 0) { //获取调用者Activity的信息记录对象 sourceRecord = mHistory.get(index); //requestCode等于-1则不进入 if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } } final int launchFlags = intent.getFlags(); /*处理标记位FLAG_ACTIVITY_FORWARD_RESULT。当有这个标记时,表示启动Activity时使用的是startActivityForResult。*/ if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { if (requestCode >= 0) { return START_FORWARD_AND_REQUEST_CONFLICT; } resultRecord = sourceRecord.resultTo; resultWho = sourceRecord.resultWho; requestCode = sourceRecord.requestCode; sourceRecord.resultTo = null; if (resultRecord != null) { resultRecord.removeResultsLocked( sourceRecord, resultWho, requestCode); } } //从Intent中无法找到相应的Component if (err == START_SUCCESS && intent.getComponent() == null) { err = START_INTENT_NOT_RESOLVED; } //从Intent中无法找到相应的ActivityInfo if (err == START_SUCCESS && aInfo == null) { err = START_CLASS_NOT_FOUND; } //检查调用者是否有权限来启动指定的Activity final int perm = mService.checkComponentPermission(aInfo.permission, callingPid,callingUid, aInfo.applicationInfo.uid, aInfo.exported); ... //创建要启动的Activity的Activity信息记录对象 ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,intent, resolvedType, aInfo, mService.mConfiguration,resultRecord, resultWho, requestCode, componentSpecified); ... //调用startActivityUncheckedLocked,见3.4小结 err = startActivityUncheckedLocked(r, sourceRecord, grantedUriPermissions, grantedMode, onlyIfNeeded, true); if (mDismissKeyguardOnNextActivity && mPausingActivity == null) { mDismissKeyguardOnNextActivity = false; mService.mWindowManager.dismissKeyguard(); } return err; }

主要是做权限检查,目标Activity信息的记录…等等

3.4 ActivityStack.startActivityUncheckedLocked

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, Uri[] grantedUriPermissions, int grantedMode, boolean onlyIfNeeded, boolean doResume) { final Intent intent = r.intent; final int callingUid = r.launchedFromUid; //获得Intent中的启动标志 int launchFlags = intent.getFlags(); //启动模式及Intent标志位处理 ... //见3.5小结 startActivityLocked(r, newTask, doResume, keepCurTransition); return START_SUCCESS; }

这个方法中主要涉及了一些列的启动模式和Intent标志的处理,最后调用了与3.3小结中参数不同的startActivityLocked方法。

3.5 ActivityStack.startActivityLocked()

private final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition) { final int NH = mHistory.size(); int addPos = -1; //判断目标Activity是不是在新Task栈中启动,即newTask变量为false if (!newTask) { // 如果不在新Task中系统,那么找到目标Activity位于那个task中 ... } //将Activity放在Task的最顶层,并在WMS注册Token ... if (doResume) { //见3.6小结 resumeTopActivityLocked(null); } }

3.6 ActivityStack.resumeTopActivityLocked()

final boolean resumeTopActivityLocked(ActivityRecord prev) { // 从mHistory中获得ActivityStack最上面的有效的Activity ActivityRecord next = topRunningActivityLocked(null); final boolean userLeaving = mUserLeaving; mUserLeaving = false; //如果next为null,那么我们就要启动Launcher主界面。 if (next == null) { // There are no more activities! Let's just start up the // Launcher... if (mMainStack) { return mService.startHomeActivityLocked(); } } next.delayedResume = false; //判断当前运行的Activity是否是目标Activity,是的话就不要重复启动了 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { mService.mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); return false; } ... // mStoppingActivities.remove(next); mGoingToSleepActivities.remove(next); next.sleeping = false; mWaitingVisibleActivities.remove(next); if (mPausingActivity != null) { if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity); return false; } //当mPausingActivity不为null,说明目前正在pause前一个activity,我们需要等待操作结束,所以直接return if (mResumedActivity != null) { if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing"); startPausingLocked(userLeaving, false); return true; } if (prev != null && prev != next) { //next.nowVisible为false的话表示即将启动的Activity是不可见的 if (!prev.waitingVisible && next != null && !next.nowVisible) { prev.waitingVisible = true; mWaitingVisibleActivities.add(prev); if (DEBUG_SWITCH) Slog.v( TAG, "Resuming top, waiting visible to hide: " + prev); } else { if (prev.finishing) { mService.mWindowManager.setAppVisibility(prev.appToken, false); } else { ... } } } ... if (prev != null) { if (prev.finishing) { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare close transition: prev=" + prev); if (mNoAnimActivities.contains(prev)) { mService.mWindowManager.prepareAppTransition( WindowManagerPolicy.TRANSIT_NONE, false); } else { mService.mWindowManager.prepareAppTransition(prev.task == next.task? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE: WindowManagerPolicy.TRANSIT_TASK_CLOSE, false); } //通知WMS前一个显示的Activity即将被隐藏 mService.mWindowManager.setAppWillBeHidden(prev.appToken); //通知WMS目标Activity正在成为可见 mService.mWindowManager.setAppVisibility(prev.appToken, false); } else { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev); if (mNoAnimActivities.contains(next)) { mService.mWindowManager.prepareAppTransition( WindowManagerPolicy.TRANSIT_NONE, false); } else { mService.mWindowManager.prepareAppTransition(prev.task == next.task ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN : WindowManagerPolicy.TRANSIT_TASK_OPEN, false); } } if (false) { mService.mWindowManager.setAppWillBeHidden(prev.appToken); mService.mWindowManager.setAppVisibility(prev.appToken, false); } } else if (mHistory.size() > 1) { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous"); if (mNoAnimActivities.contains(next)) { mService.mWindowManager.prepareAppTransition( WindowManagerPolicy.TRANSIT_NONE, false); } else { mService.mWindowManager.prepareAppTransition( WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, false); } } //表示目标Activity所属的进程中已有实例在运行 if (next.app != null && next.app.thread != null) { //通知WMS目标Activity正在成为可见 mService.mWindowManager.setAppVisibility(next.appToken, true); //跟新一系列的全局变量 ActivityRecord lastResumedActivity = mResumedActivity; ActivityState lastState = next.state; mService.updateCpuStats(); //设置Activity状态为resumed next.state = ActivityState.RESUMED; mResumedActivity = next; next.task.touchActiveTime(); if (mMainStack) { mService.addRecentTaskLocked(next.task); } mService.updateLruProcessLocked(next.app, true, true); updateLRUListLocked(next); // Have the window manager re-evaluate the orientation of // the screen based on the new activity order. boolean updated = false; if (mMainStack) { synchronized (mService) { Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, next.mayFreezeScreenLocked(next.app) ? next.appToken : null); if (config != null) { next.frozenBeforeDestroy = true; } updated = mService.updateConfigurationLocked(config, next, false, false); } } if (!updated) { ActivityRecord nextNext = topRunningActivityLocked(null); if (nextNext != next) { // Do over! mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); } if (mMainStack) { mService.setFocusedActivityLocked(next); } ensureActivitiesVisibleLocked(null, 0); mService.mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); return true; } try { ArrayList a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { next.app.thread.scheduleSendResult(next.appToken, a); } } if (next.newIntents != null) { next.app.thread.scheduleNewIntent(next.newIntents, next.appToken); } EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, System.identityHashCode(next), next.task.taskId, next.shortComponentName); next.sleeping = false; showAskCompatModeDialogLocked(next); next.app.pendingUiClean = true; //通知目标线程resume指定的Activity next.app.thread.scheduleResumeActivity(next.appToken, mService.isNextTransitionForward()); checkReadyForSleepLocked(); } catch (Exception e) { ... startSpecificActivityLocked(next, true, false); return true; } ... } else { //表明目标Activity在进程中没有实例存在 if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } else { if (SHOW_APP_STARTING_PREVIEW) { mService.mWindowManager.setAppStartingWindow( next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked( next.info.applicationInfo), next.nonLocalizedLabel, next.labelRes, next.icon, next.windowFlags, null, true); } if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next); } //见目标4.1小节 startSpecificActivityLocked(next, true, true); } return true; }

主要功能:

找不到需要resume的Activity,表示需要启动Launcher主界面。否则,需要执行startPausingLocked()来pause前一个Activity与WMS通讯,告知需要准备隐藏前一个Activity,准备显示其另一个Activity当目标进程中存在目标Activity,则跟新一系列的全局变量,resumeActivity;否则进入startSpecificActivityLocked环节

三. AMS中的最后一步

4.1 ActivityStack.startSpecificActivityLocked

private final void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // 根据目标线程的processName,以及调用者的id(uid)来获得目标进程的ProcessRecord对象,从名称可以看出是进程的信息记录对象。 ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid); if (r.launchTime == 0) { r.launchTime = SystemClock.uptimeMillis(); if (mInitialStartTime == 0) { mInitialStartTime = r.launchTime; } } else if (mInitialStartTime == 0) { mInitialStartTime = SystemClock.uptimeMillis(); } //当目标进程存在时,进入这个if判断 if (app != null && app.thread != null) { try { app.addPackage(r.info.packageName); //调用realStartActivityLocked真正开始启动目标Activity realStartActivityLocked(r, app, andResume, checkConfig); //启动完成直接return return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } } //代码执行到这里,就表示目标进程不存在,具体见4.2小节 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false); }

4.2 ProcessRecord.startProcessLocked()

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting) { // 根据目标线程的processName,以及调用者的id(uid)来获得目标进程的ProcessRecord对象,从名称可以看出是进程的信息记录对象。 ProcessRecord app = getProcessRecordLocked(processName, info.uid); ... //获得hostingNameStr字符串 String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null; ... //见4.3小节 startProcessLocked(app, hostingType, hostingNameStr); return (app.pid != 0) ? app : null; }

4.3ProcessRecord.startProcessLocked()

private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { ... try { //获得uid,gids值; int uid = app.info.uid; int[] gids = null; try { gids = mContext.getPackageManager().getPackageGids( app.info.packageName); } catch (PackageManager.NameNotFoundException e) { Slog.w(TAG, "Unable to retrieve gids", e); } ... //见5.1小节 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, app.info.targetSdkVersion, null); } catch (RuntimeException e) { // XXX do better error recovery. app.pid = 0; Slog.e(TAG, "Failure starting process " + app.processName, e); } }

Process.start方法是一个静态方法可以直接调用

五. Process中与Zygote进程的通讯

5.1 Process.start

public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int targetSdkVersion, String[] zygoteArgs) { try { //见5.2小节 return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, targetSdkVersion, zygoteArgs); } catch (ZygoteStartFailedEx ex) { ... } }

5.2 Process.startViaZygote

private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int targetSdkVersion, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { //创建一个泛型为String的list容器, ArrayList<String> argsForZygote = new ArrayList<String>(); // --runtime-init, --setuid=, --setgid=, // and --setgroups= must go first //在list容器中封装一些必要字符串信息。 argsForZygote.add("--runtime-init"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); ... if (gids != null && gids.length > 0) { StringBuilder sb = new StringBuilder(); sb.append("--setgroups="); int sz = gids.length; for (int i = 0; i < sz; i++) { if (i != 0) { sb.append(','); } sb.append(gids[i]); } argsForZygote.add(sb.toString()); } if (niceName != null) { argsForZygote.add("--nice-name=" + niceName); } //processClass字符串的值为android.app.ActivityThread argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } //见5.3小节 return zygoteSendArgsAndGetResult(argsForZygote); } }

该过程主要工作是生成argsForZygote容器,保存了进程的uid、gid、groups、target-sdk、nice-name等一系列的参数。

5.3 Process.zygoteSendArgsAndGetResult

private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)throws ZygoteStartFailedEx { //调用这个方法,在这个方法中会通过Socket唤醒Zytote进程,见5.4小节 openZygoteSocketIfNeeded(); //sZygoteWriter在openZygoteSocketIfNeeded方法中初始化; try { //通过Socket将args中记录的信息发送给Zytote进程 sZygoteWriter.write(Integer.toString(args.size())); sZygoteWriter.newLine(); int sz = args.size(); for (int i = 0; i < sz; i++) { String arg = args.get(i); if (arg.indexOf('\n') >= 0) { throw new ZygoteStartFailedEx( "embedded newlines not allowed"); } sZygoteWriter.write(arg); sZygoteWriter.newLine(); } //flush刷出缓冲区数据 sZygoteWriter.flush(); // Should there be a timeout on this? ProcessStartResult result = new ProcessStartResult(); //获得Zygote进程Fork出的子进程,即欲创建的目标进程。 result.pid = sZygoteInputStream.readInt(); if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } result.usingWrapper = sZygoteInputStream.readBoolean(); return result; } catch (IOException ex) { try { if (sZygoteSocket != null) { sZygoteSocket.close(); } } catch (IOException ex2) { // we're going to fail anyway Log.e(LOG_TAG,"I/O exception on routine close", ex2); } sZygoteSocket = null; throw new ZygoteStartFailedEx(ex); } }

在调用openZygoteSocketIfNeeded之后会建立与Zytote进程的Socket通道

5.3 Process.openZygoteSocketIfNeeded

private static void openZygoteSocketIfNeeded() throws ZygoteStartFailedEx { int retryCount; if (sPreviousZygoteOpenFailed) { retryCount = 0; } else { retryCount = 10; } for (int retry = 0; (sZygoteSocket == null) && (retry < (retryCount + 1)); retry++ ) { if (retry > 0) { try { Log.i("Zygote", "Zygote not up yet, sleeping..."); Thread.sleep(ZYGOTE_RETRY_MILLIS); } catch (InterruptedException ex) { // should never happen } } //创建Socket客户端 try { sZygoteSocket = new LocalSocket(); //调用connect方法,唤醒Zygote进程端 sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED)); sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream()); sZygoteWriter = new BufferedWriter(newOutputStreamWriter(sZygoteSocket.getOutputStream()), 256); sPreviousZygoteOpenFailed = false; break; } catch (IOException ex) { if (sZygoteSocket != null) { try { sZygoteSocket.close(); } catch (IOException ex2) { Log.e(LOG_TAG,"I/O exception on close after exception", ex2); } } sZygoteSocket = null; } } if (sZygoteSocket == null) { sPreviousZygoteOpenFailed = true; throw new ZygoteStartFailedEx("connect failed"); } }

这个方法的主要作用就是创建Socket,然后唤醒Zygote进程,并连接Zygote进程端。

六. Zygote进程fork子进程

Zygote进程是init进程fork的子进程,进程启动之后调用ZygoteInit.main()方法,经过创建socket管道,预加载资源后,最后调用runSelectLoop()方法。

6.1 ZygoteInit.runSelectLoopMode

private static void runSelectLoopMode() throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList(); ArrayList<ZygoteConnection> peers = new ArrayList(); FileDescriptor[] fdArray = new FileDescriptor[4]; //sServerSocket是socket通信中的服务端 fds.add(sServerSocket.getFileDescriptor()); peers.add(null); int loopCount = GC_LOOP_COUNT; while (true) { //循环一定次数进行gc int index; if (loopCount <= 0) { gc(); loopCount = GC_LOOP_COUNT; } else { loopCount--; } try { fdArray = fds.toArray(fdArray); index = selectReadable(fdArray); } catch (IOException ex) { throw new RuntimeException("Error in select()", ex); } if (index < 0) { throw new RuntimeException("Error in select()"); } else if (index == 0) { //index等于0,表示有客户端连接Zygote进程,创建ZygoteConnection对象,见6.2小节 ZygoteConnection newPeer = acceptCommandPeer(); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); //index>0,则代表通过socket接收来自Client的数据,执行相应操作,见6.3小节 } else { boolean done; done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } } } } 客户端通过openZygoteSocketIfNeeded()与zygote进程建立连接。zygote进程收到客户端连接请求后执行accept();然后再创建ZygoteConnection对象,并添加到fds容器中;建立连接之后,可以跟客户端通信,进入runOnce()方法来接收客户端数据,并执行进程创建工作。

6.2 ZygoteInit.acceptCommandPeer

private static ZygoteConnection acceptCommandPeer() { try { return new ZygoteConnection(sServerSocket.accept()); } catch (IOException ex) { throw new RuntimeException( "IOException during accept()", ex); } }

6.3 ZygoteConnection.runOnce

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; //读取socket客户端发送过来的参数列表 try { args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { Log.w(TAG, "IOException on command socket " + ex.getMessage()); closeSocket(); return true; } if (args == null) { // EOF reached. closeSocket(); return true; } /** the stderr of the most recent request, if avail */ PrintStream newStderr = null; if (descriptors != null && descriptors.length >= 3) { newStderr = new PrintStream( new FileOutputStream(descriptors[2])); } int pid = -1; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; try { //将Client发送过来的参数列表通过Arguments解析 parsedArgs = new Arguments(args); ... //见6.3小节 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits); } catch (IOException ex) { logAndPrintError(newStderr, "Exception creating pipe", ex); } catch (ErrnoException ex) { logAndPrintError(newStderr, "Exception creating pipe", ex); } catch (IllegalArgumentException ex) { logAndPrintError(newStderr, "Invalid zygote arguments", ex); } catch (ZygoteSecurityException ex) { logAndPrintError(newStderr, "Zygote security policy prevents request: ", ex); } try { if (pid == 0) { //子进程中执行 IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; //见小节6.4 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); //不会到达此处,子进程预期会抛出ZygoteInit.MethodAndArgsCaller或执行exec() return true; } else { // 在父进程中执行,如果pid小于0表示fork失败 IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } }

6.3 Zygote.forkAndSpecialize

public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits) { //完成一些fork前的初始化工作:停止Daemon子线程,完成GC堆的初始化 preFork(); //直接调用了一个native方法 int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits); //fork新进程后,启动Zygote的4个Daemon线程,java堆整理,引用队列,以及析构线程。 postFork(); return pid; } //通过jni调用native方法,返回值为Zygote进程fork的子进程的pid native public static int nativeForkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits);

6.4 ZygoteConnection.handleChildProc

private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { /* * Close the socket, unless we're in "peer wait" mode, in which * case it's used to track the liveness of this process. */ if (parsedArgs.peerWait) { try { ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true); sPeerWaitSocket = mSocket; } catch (IOException ex) { Log.e(TAG, "Zygote Child: error setting peer wait " + "socket to be close-on-exec", ex); } } else { //关闭Socket两端的连接 closeSocket(); ZygoteInit.closeServerSocket(); } ... //设置进程的名称 if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } //Socket Client端在封装时封装了"--runtime-init"字符串,Arguments解析时会将parsedArgs.runtimeInit初始化为true if (parsedArgs.runtimeInit) { if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, pipeFd, parsedArgs.remainingArgs); } else { //见6.5小节 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); } } else { String className; try { className = parsedArgs.remainingArgs[0]; } catch (ArrayIndexOutOfBoundsException ex) { logAndPrintError(newStderr, "Missing required class name argument", null); return; } String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1]; System.arraycopy(parsedArgs.remainingArgs, 1, mainArgs, 0, mainArgs.length); if (parsedArgs.invokeWith != null) { WrapperInit.execStandalone(parsedArgs.invokeWith, parsedArgs.classpath, className, mainArgs); } else { ClassLoader cloader; if (parsedArgs.classpath != null) { cloader = new PathClassLoader(parsedArgs.classpath, ClassLoader.getSystemClassLoader()); } else { cloader = ClassLoader.getSystemClassLoader(); } try { //通过反射调用AcitivityThread的main方法 ZygoteInit.invokeStaticMain(cloader, className, mainArgs); } catch (RuntimeException ex) { logAndPrintError(newStderr, "Error starting.", ex); } } } }

6.5 RuntimeInit.zygoteInit

public static final void zygoteInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); //重定向log输出 redirectLogStreams(); //一些通用的初始化,见6.6小节 commonInit(); //Zytote的初始化,见6.7小节 zygoteInitNative(); //应用初始化,见6.8小节 applicationInit(targetSdkVersion, argv); }

6.6 RuntimeInit.commonInit

private static final void commonInit() { //设置默认的没有catch的异常的处理handler Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); int hasQwerty = getQwertyKeyboard(); if (DEBUG) Slog.d(TAG, ">>>>> qwerty keyboard = " + hasQwerty); if (hasQwerty == 1) { System.setProperty("qwerty", "1"); } //设置时区 TimezoneGetter.setInstance(new TimezoneGetter() { @Override public String getId() { return SystemProperties.get("persist.sys.timezone"); } }); TimeZone.setDefault(null); //重置log配置 LogManager.getLogManager().reset(); new AndroidConfig(); // 设置默认的HTTP User-agent格式,用于 HttpURLConnection。 String userAgent = getDefaultUserAgent(); System.setProperty("http.agent", userAgent); // 设置socket的tag,用于网络流量统计 NetworkManagementSocketTagger.install(); String trace = SystemProperties.get("ro.kernel.android.tracing"); if (trace.equals("1")) { Slog.i(TAG, "NOTE: emulator trace profiling enabled"); Debug.enableEmulatorTraceOutput(); } initialized = true; }

一些通用的初始化

6.7 RuntimeInit.zygoteInitNative()

static void com_android_internal_os_RuntimeInit_zygoteInit(JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }
6.7.1 app_main.onZygoteInit
virtual void onZygoteInit() { sp<ProcessState> proc = ProcessState::self(); //启动binder线程池 proc->startThreadPool(); }

6.8 RuntimeInit.applicationInit

private static void applicationInit(int targetSdkVersion, String[] argv) throws ZygoteInit.MethodAndArgsCaller { //设置虚拟机的内存利用率 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; try { //解析参数 args = new Arguments(argv); } catch (IllegalArgumentException ex) { Slog.e(TAG, ex.getMessage()); // let the process exit return; } //见6.9小节 invokeStaticMain(args.startClass, args.startArgs); }

6.9 RuntimeInit.invokeStaticMain

private static void invokeStaticMain(String className, String[] argv) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; //其中,className的值为"android.app.ActivityThread" try { //通过类名反射获得Class字节码对象cl cl = Class.forName(className); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { //反射获得cl中main方法的Method对象 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); } //直接throw回到ZygoteInit.main()。这样做能清空栈帧,提高栈帧利用率,见7.1小节 throw new ZygoteInit.MethodAndArgsCaller(m, argv); }

7.1

public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); if (sMainThreadHandler == null) { sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach(false); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

此时,就直接调用到了我们熟悉的ActivityThread中main方法。 App启动流程分析 (下)

转载请注明原文地址: https://www.6miu.com/read-68257.html

最新回复(0)