美文网首页
应用启动流程分析

应用启动流程分析

作者: Jeffrey599 | 来源:发表于2021-04-27 18:06 被阅读0次

    一、系统环境启动

    image

    Android手机开机启动Linux内核,它会去加载system/core/init/init.rc文件,启动init进程。

    init进程的主要作用:

    • 负责开关机界面

    • 文件系统的创建和挂载

    • 启动Zygote(孵化器)进程

    • 启动ServiceManager,它是Binder的“DNS”,管理着所有Android系统服务

    在init进程启动后会去fork一个叫Zygote的进程,顾名思义,Zygote相当于一个孵化器,它的作用主要是:

    • 创建一个名叫zygote的socket,用来和客户端进程通信

    • 启动SystemServer进程

    • 当发来socket请求,它可以fork自身创建出一个新的进程

    SystemServer是Zygote创建的第一个进程,它的作用如下:

    • 启动binder线程池,保证与其他进程通信

    • 启动各个系统服务并将其注册到ServiceManager中

      • BootstrapServices(引导服务):ActivityManagerService、PowerManagerService、UserManagerService等
    • CoreServices(核心服务):BatteryService、UsageService等

    • OtherServices(其他服务):AccountManagerService、WindowManagerService等

    // SystemServer.java
    // Start services.
    try {
    traceBeginAndSlog("StartServices");
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
    Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
    traceEnd();
    }
    
    

    可以看到SystemServer创建了应用所需要的各项系统服务,它们运行在system_server(系统进程),应用进程通过binder通信调用相应的服务,在AMS被创建后,将首先启动Lancher进程,Lancher也是一个应用,它被启动之后,会从PMS获取已安装的应用列表展示给用户,用户点击图标会打开对应的应用。

    二、Activity相关角色介绍

    image
    • ActivityStackSupervisor

      • ActivityStack的管理者,内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个ActivityStack
    • ActivityStack

      • 保存TaskRecord
    • TaskRecord

      • 以栈的方式保存ActivityRecord,也就是常说的任务栈
    • ActivityRecord

      • 保存了Activity相关信息,对应一个Activity
    image

    通过adb来dump出相关信息:

    //执行 adb shell dumpsys activity activities
    
    ...
    TaskRecord{3f6aa9e #24 A=com.google.android.apps.messaging U=0 StackId=10 sz=2}
          userId=0 effectiveUid=u0a115 mCallingUid=u0a103 mUserSetupComplete=true mCallingPackage=com.google.android.apps.nexuslauncher
          affinity=com.google.android.apps.messaging
          intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.google.android.apps.messaging/.ui.ConversationListActivity}
          origActivity=com.google.android.apps.messaging/.ui.ConversationListActivity
          mActivityComponent=com.google.android.apps.messaging/.ui.conversationlist.ConversationListActivity
          autoRemoveRecents=false isPersistable=true numFullscreen=2 activityType=1
          rootWasReset=true mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
          Activities=[ActivityRecord{25f7fa9 u0 com.google.android.apps.messaging/.ui.ConversationListActivity t24}, ActivityRecord{f796dbd u0 com.google.android.apps.messaging/.ui.conversation.ConversationActivity t24}]
          askedCompatMode=false inRecents=true isAvailable=true
          mRootProcess=ProcessRecord{774c038 4253:com.google.android.apps.messaging/u0a115}
          stackId=10
          hasBeenVisible=true mResizeMode=RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION mSupportsPictureInPicture=false isResizeable=true lastActiveTime=454547 (inactive for 633s)
    ...
    
    

    三、应用启动入口

    image

    从上面时序图可以看到,启动Activity前置操作主要如下几步:

    1. 桌面Activity调用startActivityForResult
    2. Instrumentation调用execStartActivity通过binder通信将intent发送给AMS(位于系统进程)
    3. AMS收到消息之后会先校验intent请求的合法性
    4. 检验成功后,ActivityStack调用resumeTopActivityInnerLocked,其中会调用startPausingLocked去将当前栈顶Activity的状态改为Pause,这里也是通过binder通信
    5. 然后ActivityStackSupervisor会判断当前请求启动的Activity所属进程是否启动(若manifest未设置process属性默认应用主进程),未启动则调用Process.strat()通过Zygote进程去fork出一个新的应用进程(系统进程和Zygote通过socket通信),在该进程中通过反射去调用ActivityThread.main(),即为应用启动的主入口。
    // ActivityThread.java
    
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
    
    // 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);
    
    Environment.initForCurrentUser();
    
    // Set the reporter for event logging in libcore
    EventLogger.setReporter(new EventLoggingReporter());
    
    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
    Process.setArgV0("<pre-initialized>");
    
    Looper.prepareMainLooper();
    
    // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
    long startSeq = 0;
        if (args != null) {
    for (int i = args.length - 1; i >= 0; --i) {
    if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
    }
            }
        }
        ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    
        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方法主要作用如下:

    1. 初始化了主线程Looper对象
    2. 初始化ActivityThread对象同时调用attach方法,通过AMS为应用绑定一个Application,执行Application.onCreate()
    3. 指定主线程的Handler为H
    4. 调用Looper.loop()开启消息轮询,之后的操作将通过Android消息机制来实现,H中定义了各种类型的消息
    class H extends Handler {
        public static final int BIND_APPLICATION        = 110;
        public static final int EXIT_APPLICATION        = 111;
        public static final int RECEIVER                = 113;
        public static final int CREATE_SERVICE          = 114;
        public static final int SERVICE_ARGS            = 115;
        public static final int STOP_SERVICE            = 116;
    
        public static final int CONFIGURATION_CHANGED   = 118;
        public static final int CLEAN_UP_CONTEXT        = 119;
        public static final int GC_WHEN_IDLE            = 120;
        public static final int BIND_SERVICE            = 121;
        public static final int UNBIND_SERVICE          = 122;
        public static final int DUMP_SERVICE            = 123;
        public static final int LOW_MEMORY              = 124;
        public static final int PROFILER_CONTROL        = 127;
        public static final int CREATE_BACKUP_AGENT     = 128;
        public static final int DESTROY_BACKUP_AGENT    = 129;
        public static final int SUICIDE                 = 130;
        public static final int REMOVE_PROVIDER         = 131;
        public static final int ENABLE_JIT              = 132;
        public static final int DISPATCH_PACKAGE_BROADCAST = 133;
        public static final int SCHEDULE_CRASH          = 134;
        public static final int DUMP_HEAP               = 135;
        public static final int DUMP_ACTIVITY           = 136;
        public static final int SLEEPING                = 137;
        public static final int SET_CORE_SETTINGS       = 138;
        public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
        public static final int DUMP_PROVIDER           = 141;
        public static final int UNSTABLE_PROVIDER_DIED  = 142;
        public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
        public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
        public static final int INSTALL_PROVIDER        = 145;
        public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
        public static final int ENTER_ANIMATION_COMPLETE = 149;
        public static final int START_BINDER_TRACKING = 150;
        public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
        public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
        public static final int ATTACH_AGENT = 155;
        public static final int APPLICATION_INFO_CHANGED = 156;
        public static final int RUN_ISOLATED_ENTRY_POINT = 158;
        public static final int EXECUTE_TRANSACTION = 159;
        public static final int RELAUNCH_ACTIVITY = 160;
    
        ...
        }
    
    

    四、Activity启动流程

    当AMS的attachApplication被应用侧调用后,会执行到realStartActivityLocked方法,如下:

     // ActivityStackSupervisor.java
      final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
                    ...
                    // Create activity launch transaction.
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                            r.appToken);
                    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                            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, mService.isNextTransitionForward(),
                            profilerInfo));
    
                    // Set desired final state.
                    final ActivityLifecycleItem lifecycleItem;
                    if (andResume) {
                        lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                    } else {
                        lifecycleItem = PauseActivityItem.obtain();
                    }
                    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
                    // Schedule transaction.
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                    ...
    
            return true;
        }
    
    

    在ActivityStackSupervisor.realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,最后调用ClientLifecycleManager.scheduleTransaction方法执行。

    // TransactionExecutor.java
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
    
        executeCallbacks(transaction);
    
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
    
    

    ClientLifecycleManager会执行LaunchActivityItem.excute(),最终会调到ActivityThread.performLaunchActivity()

    // ActivityThread.java
    
    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) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate activity " + component
                        + ": " + e.toString(), e);
                }
            }
    
            try {
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
                if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
                if (localLOGV) Slog.v(
                        TAG, r + ": app=" + app
                        + ", appName=" + app.getPackageName()
                        + ", pkg=" + r.packageInfo.getPackageName()
                        + ", comp=" + r.intent.getComponent().toShortString()
                        + ", dir=" + r.packageInfo.getAppDir());
    
                if (activity != null) {
                    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                    Configuration config = new Configuration(mCompatConfiguration);
                    if (r.overrideConfig != null) {
                        config.updateFrom(r.overrideConfig);
                    }
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                            + r.activityInfo.name + " with config " + config);
                    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) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onCreate()");
                    }
                    r.activity = activity;
                }
                r.setState(ON_CREATE);
    
                mActivities.put(r.token, r);
    
            } catch (SuperNotCalledException e) {
                throw e;
    
            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to start activity " + component
                        + ": " + e.toString(), e);
                }
            }
    
            return activity;
        }
    
    

    这里对Activity的ComponentName、ContextImpl、Activity以及Application对象进行了初始化并相互关联,然后会设置Activity的主题,最后调用Instrumentation.callActivityOnCreate方法

    //Instrumentation.java
    public void callActivityOnCreate(Activity activity, Bundle icicle,
    PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
    
    //Activity.java
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            mCanEnterPictureInPicture = true;
            restoreHasCurrentPermissionRequest(icicle);
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
            mActivityTransitionState.readState(icicle);
    
            mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                    com.android.internal.R.styleable.Window_windowNoDisplay, false);
            mFragments.dispatchActivityCreated();
            mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        }
    
    

    callActivityOnCreate被调用后就会执行Activity的performCrate方法,最后会执行Activity的onCreate方法,这样ClientTransaction的callback就被执行完了,接下来执行TransactionExecutor .executeLifecycleState方法

    // TransactionExecutor.java
    /** Transition to the final state if requested by the transaction. */
        private void executeLifecycleState(ClientTransaction transaction) {
            final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
            if (lifecycleItem == null) {
                // No lifecycle request, return early.
                return;
            }
            log("Resolving lifecycle state: " + lifecycleItem);
    
            final IBinder token = transaction.getActivityToken();
            final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    
            if (r == null) {
                // Ignore requests for non-existent client records for now.
                return;
            }
    
            // Cycle to the state right before the final requested state.
            cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
    
            // Execute the final transition with proper parameters.
            lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
            lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
        }
    
        /** Transition the client between states. */
        @VisibleForTesting
        public void cycleToPath(ActivityClientRecord r, int finish) {
            cycleToPath(r, finish, false /* excludeLastState */);
        }
    
        /**
         * Transition the client between states with an option not to perform the last hop in the
         * sequence. This is used when resolving lifecycle state request, when the last transition must
         * be performed with some specific parameters.
         */
        private void cycleToPath(ActivityClientRecord r, int finish,
                boolean excludeLastState) {
            final int start = r.getLifecycleState();
            log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);
            final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
            performLifecycleSequence(r, path);
        }
    
        /** Transition the client through previously initialized state sequence. */
        private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
            final int size = path.size();
            for (int i = 0, state; i < size; i++) {
                state = path.get(i);
                log("Transitioning to state: " + state);
                switch (state) {
                    case ON_CREATE:
                        mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                                null /* customIntent */);
                        break;
                    case ON_START:
                        mTransactionHandler.handleStartActivity(r, mPendingActions);
                        break;
                    case ON_RESUME:
                        mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                                r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                        break;
                    case ON_PAUSE:
                        mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                                false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                                "LIFECYCLER_PAUSE_ACTIVITY");
                        break;
                    case ON_STOP:
                        mTransactionHandler.handleStopActivity(r.token, false /* show */,
                                0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                                "LIFECYCLER_STOP_ACTIVITY");
                        break;
                    case ON_DESTROY:
                        mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                                0 /* configChanges */, false /* getNonConfigInstance */,
                                "performLifecycleSequence. cycling to:" + path.get(size - 1));
                        break;
                    case ON_RESTART:
                        mTransactionHandler.performRestartActivity(r.token, false /* start */);
                        break;
                    default:
                        throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
                }
            }
        }
    
    

    在executeLifecycleState方法里面,会先去调用TransactionExecutor.cycleToPath执行当前生命周期状态之前的状态,然后执行ActivityLifecycleItem.execute方法。执行cycleToPath时,因为下一个状态是

    ON_START,所以会执行mTransactionHandler.handleStartActivity(),最终会执行Activity.onStart()。

    同样的方式,ResumeActivityItem.execute方法会被执行,最终执行Activity.onResume方法,这样Activity就启动了。

    五、前一个Activity调用onStop

    在要打开的Activity执行完onResume之后,ActivityThread.handleResumeActivity()方法被执行,它会创建一个Idler,并且添加到主线程的消息队列中去。在这之后的流程会创建StopActivityItem最终去执行前一个Activity的onStop(如果Activity还是可见状态则不会执行)

    六、应用启动流程总结

    1. 系统开机后先启动init进程,init进程fork出一个Zygote进程作为其他应用进程的孵化器
    2. Zygote进程会先创建一个SystemServer进程
    3. SystemServer负责初始化各项系统服务,同时启动桌面应用
    4. 桌面应用通过PMS获取已安装应用列表展示给用户
    5. 用户点击桌面图标通过startActivity向AMS发起打开应用的请求
    6. AMS识别有效请求后,会先将当前栈顶的Activity改为pause状态,为应用请求创建进程,最终通过ActivityThread.main()进入应用的主入口
    7. Activity所在应用的进程和主线程完成初始化之后绑定Application,然后开始启动Activity,首先对Activity的ComponentName、ContextImpl、Activity以及Application对象进行了初始化并相互关联,然后设置Activity主题,最后执行onCreate->onStart->onResume方法完成Activity的启动
    8. 上述流程都执行完毕后,会去执行之前栈顶Activity的onStop

    相关文章

      网友评论

          本文标题:应用启动流程分析

          本文链接:https://www.haomeiwen.com/subject/uwrprltx.html