App启动流程分析(上)

App启动流程分析

一.概述流程

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

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

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

            // --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 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 fds = new ArrayList();
        ArrayList 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("");

        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启动流程分析 (下)

你可能感兴趣的:(android源码)