Android10 App启动Activity源码分析

目录
  • 正文
  • ActivityThread的main方法
  • Application Context对象
  • LaunchActivityItem
  • ClientLifecycleManager
  • ClientTransaction
  • TransactionExecutor
  • executeLifecycleState方法

正文

上一篇:

Android 10 App启动分析之进程创建篇(一)

上一篇文章,我们探讨了App启动过程中进程创建及初始化的流程,这篇文章我们接着上篇的内容,继续探讨App的Application和Activity的创建及启动流程。

ActivityThread的main方法

让我们把目光聚焦到ActivityThread的main方法上。

ActivityThread的源码路径为 /frameworks/base/core/java/android/app/ActivityThread

public static void main(String[] args) {
      ...
       //请注意这句话,主线程Looper在此处做了prepare的操作
       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) {
           //获取主线程的handler,其实就是ActivityThread里的mH变量
           sMainThreadHandler = thread.getHandler();
       }
       //开始循环获取主线程Message消息
       Looper.loop();
       throw new RuntimeException("Main thread loop unexpectedly exited");
   }

继续从ActivityThread的attach方法往下追踪。

private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            //执行此分支
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {
            ...
        }
        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            synchronized (mResourcesManager) {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());
                    // This actually changed the resources! Tell everyone about it.
                    if (mPendingConfiguration == null
                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                        mPendingConfiguration = globalConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    }
                }
            }
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

上述代码调用了IActivityManagerattachApplication方法,并传入了当前的ActivityThread对象以及启动序列号。我们将目光转向ActivityManagerService

 @Override
   public final void attachApplication(IApplicationThread thread, long startSeq) {
       if (thread == null) {
           throw new SecurityException("Invalid application interface");
       }
       synchronized (this) {
           int callingPid = Binder.getCallingPid();
           final int callingUid = Binder.getCallingUid();
           final long origId = Binder.clearCallingIdentity();
           attachApplicationLocked(thread, callingPid, callingUid, startSeq);
           Binder.restoreCallingIdentity(origId);
       }
   }
 private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ...
            mAtmInternal.preBindApplication(app.getWindowProcessController());
            final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
            if (app.isolatedEntryPoint != null) {
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
            } else if (instr2 != null) {
                thread.bindApplication(processName, appInfo, providers,
                        instr2.mClass,
                        profilerInfo, instr2.mArguments,
                        instr2.mWatcher,
                        instr2.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions);
            }
            if (profilerInfo != null) {
                profilerInfo.closeFd();
                profilerInfo = null;
            }
            // Make app active after binding application or client may be running requests (e.g
            // starting activities) before it is ready.
            app.makeActive(thread, mProcessStats);
            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
            mProcessList.updateLruProcessLocked(app, false, null);
            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            // todo: Yikes!  What should we do?  For now we will try to
            // start another process, but that could easily get us in
            // an infinite loop of restarting processes...
            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName));
            return false;
        }
        // Remove this record from the list of starting applications.
        mPersistentStartingProcesses.remove(app);
        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
                "Attach application locked removing on hold: " + app);
        mProcessesOnHold.remove(app);
        boolean badApp = false;
        boolean didSomething = false;
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        // Find any services that should be running in this process...
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
        ...
        return true;
    }

上面这段内容有两段关键的语句,一是调用了 IApplicationThreadbindApplication方法;二是调用了ActivityTaskManagerInternalattachApplication方法。我们先来看位于ActivityThread中的bindApplication这个调用。

 public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions) {
            ...
            sendMessage(H.BIND_APPLICATION, data);
        }

方法的结尾,发送了一条what值为H.BIND_APPLICATION的消息。

我们去Handler中找到这条消息的代码段。

 switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
 private void handleBindApplication(AppBindData data) {
        // Register the UI Thread as a sensitive thread to the runtime.
        ...
        Application app;
        try {
            //在这里创建了Application对象
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            // Propagate autofill compat state
            app.setAutofillOptions(data.autofillOptions);
            // Propagate Content Capture options
            app.setContentCaptureOptions(data.contentCaptureOptions);
            mInitialApplication = app;
            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                }
            }
            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
            try {
                //在这里调用了Application onCreate方法
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
            }
        } finally {
            // If the app targets < O-MR1, or doesn't change the thread policy
            // during startup, clobber the policy to maintain behavior of b/36951662
            if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                    || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
                StrictMode.setThreadPolicy(savedPolicy);
            }
        }
        // 加载字体资源
        FontsContract.setApplicationContextForResources(appContext);
        if (!Process.isIsolated()) {
            try {
                final ApplicationInfo info =
                        getPackageManager().getApplicationInfo(
                                data.appInfo.packageName,
                                PackageManager.GET_META_DATA /*flags*/,
                                UserHandle.myUserId());
                if (info.metaData != null) {
                    final int preloadedFontsResource = info.metaData.getInt(
                            ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
                    if (preloadedFontsResource != 0) {
                        data.info.getResources().preloadFonts(preloadedFontsResource);
                    }
                }
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

app = data.info.makeApplication(data.restrictedBackupMode, null);

Application Context对象

这段代码是一段关键代码,它创建了Application以及全局的Application Context对象, 我们深入往下看一下:

源码位置为 frameworks/base/core/java/android/app/LoadedApk.java

 public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        Application app = null;
        //如果manifest application标签的name属性指定了application类,则使用指定的类,否则默认使用android.app.Application
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            //创建全局的Application Context
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //创建Application对象
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }
        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }
            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        return app;
    }
  static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        //在这里将applicationContext设置到application对象中
        app.attach(context);
        return app;
    }

第一阶段,Application的创建与初始化已经至此结束,接下来我们将目光放到ActivityTaskManagerInternalattachApplication方法。

 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                return mRootActivityContainer.attachApplication(wpc);
            }
        }

进入了RootActivityContainer中继续执行。

 boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack != null) {
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

ActivityStackSupervisorrealStartActivityLocked方法去真正准备启动Activity。

 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        try {
            ...
            try {
               ...
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
                final DisplayContent dc = r.getDisplay().mDisplayContent;
                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, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));
                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
               ...
            } catch (RemoteException e) {
               ...
            }
        } finally {
            endDeferResume();
        }
        ...
        return true;
    }

为了解释清楚上述过程,我们必须先得认识一下ClientTransaction及其一系列相关的类。

相关联的类有以下几个:ClientTransactionTransactionExecutorClientLifecycleManager以及LaunchActivityItem,我们一个一个来分析。

LaunchActivityItem

LaunchActivityItem实现了BaseClientRequestinterface。这个接口里定义了三个十分重要的方法。

  • preExecute 在请求前进行预处理
  • execute 执行请求
  • postExecute 执行请求后的后续处理 这种设计方式是不是很眼熟!AsyncTask也是基于这种模式设计的,各位读者不妨自行联想类比一下。

LaunchActivityItem这个类设计的目的是什么呢?从名字上来讲,我们很容易想到,它主要的作用就是用来启动一个Activity的,具体反应在它重载的excute方法。

 @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

看到这句话了么,client.handleLaunchActivity(r, pendingActions, null /* customIntent */);client这个对象是什么?我们可以翻阅一下代码的调用链,可以发现client是一个ActivityThread对象,它最终调用的是ActivityThread中的handleLaunchActivity方法。

除了LauncherActivityItem以外,我们还有abstract的ActivityLifecycleItem类,在这个类中定义了一系列的生命周期状态,具体如下:

public static final int UNDEFINED = -1;
 public static final int PRE_ON_CREATE = 0;
 public static final int ON_CREATE = 1;
 public static final int ON_START = 2;
 public static final int ON_RESUME = 3;
 public static final int ON_PAUSE = 4;
 public static final int ON_STOP = 5;
 public static final int ON_DESTROY = 6;
 public static final int ON_RESTART = 7;

这些状态的值基本按照Activity的生命周期的顺序,以1为步长递增定义。为什么这么设计,我们后续会讲到。

除此之外,系统还定义了StopActivityItemNewIntentItemDestroyActivityItem等等一系列类似的类,这些类都是为了实现具体的和Activity生命周期有关的任务,并按照 预处理——执行——事后处理 的模板编写业务。

除此之外,这些类其中有一部分还有一个作用,就是确定客户端在执行事务后最终应处于的生命周期状态。

ClientLifecycleManager

生命周期管理类,它能够组合多个客户端生命周期变换的请求或回调事务,并将它们作为单个事务执行。这个方法里的内容非常简单,我们主要来关注一下它的scheduleTransaction的方法。

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }

根据上述源码,可以看出它调用了传入的ClientTransactionschedule方法。

ClientTransaction

ClientTransaction是一个保存可以发送到客户端的消息序列的容器。它包含了三个比较重要的方法, setLifecycleStateRequestaddCallbackschedule,分别用于设置目标生命周期状态和事务方法,以及执行事务。

我们来看一下schedule这个方法:

public void schedule() throws RemoteException {
     mClient.scheduleTransaction(this);
 }

代码的内容非常简单,它将schedule的操作重新分发给了mClient变量,这里的mClient,指的是ActivityThread实例。

public void executeTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        getTransactionExecutor().execute(transaction);
        transaction.recycle();
    }

这里首先调用了这样一条语句,transaction.preExecute(this),用于执行事务前的预处理操作。

  public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i &lt; size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

可以看到,它实际调用了通过setLifecycleStateRequestaddCallback两个方法设置进来的对象的preExecute方法。在实际Activity启动流程中,对应的是LaunchActivityItemResumeActivityItem两个类的preExecute方法。

TransactionExecutor

TransactionExecutor是负责管理事务以正确的顺序执行的类。

 public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }

它首先会通过executeCallbacks方法,执行ClientTransactionadd的所有Callback的executepostExecute方法,具体如下:

  public void executeCallbacks(ClientTransaction transaction) {
       ...
       //获取目标生命周期状态
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
        final int size = callbacks.size();
        for (int i = 0; i &lt; size; ++i) {
           ...
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...
        }
    }

让我们回到Activity的启动流程的代码中,clientTransaction加入了一个Callback————LaunchActivityItem,从上文可以知,这个类的execute方法里有这么一段代码client.handleLaunchActivity(r, pendingActions, null /* customIntent */);,去负责启动Activity。

executeLifecycleState方法

  private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        if (r == null) {
            //第一次启动获得的r为null,实际上会走此分支,只有在performLaunchActivity方法调用后,r才不为null
            return;
        }
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

我们重点关注一下cycleToPath方法:

 private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Cycle activity: "
                    + getShortActivityName(r.token, mTransactionHandler)
                    + " from: " + getStateName(start) + " to: " + getStateName(finish)
                    + " excludeLastState: " + excludeLastState);
        }
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

mHelper.getLifecyclePath(start, finish, excludeLastState):根据当前Activity所处的状态与目标生命周期状态,生成一个包含该状态区间内所有状态的Int数组。

  private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            if (DEBUG_RESOLVER) {
                Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                        + getShortActivityName(r.token, mTransactionHandler)
                        + " to state: " + getStateName(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);
            }
        }
    }

performLifecycleSequence开始负责按顺序执行IntArray区间里的状态变换。

让我们重新回到Activity的启动流程上,从handleLaunchActivity继续往下追踪:

 public Activity handleLaunchActivity(ActivityClientRecord r,
      ...
        final Activity a = performLaunchActivity(r, customIntent);
      ...
    }
  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();
            //通过newInstance创建Activity实例
            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);
                //调用attach方法,开始初始化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,
                        r.assistToken);
                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 {
                    //调用Activity的onCreate方法
                    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);
            // updatePendingActivityConfiguration() reads from mActivities to update
            // ActivityClientRecord which runs in a different thread. Protect modifications to
            // mActivities to avoid race.
            synchronized (mResourcesManager) {
                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;
    }

Application app = r.packageInfo.makeApplication(false, mInstrumentation);

有些读者可能会对这句话有些疑问,前面不是已经创建过Application对象了吗,怎么这里还调用一遍,不是说一个进程里只能有一个Application对象吗?

我们进入makeApplication方法里看一下,第一句话就解释了原因:

  if (mApplication != null) {
            return mApplication;
        }

所以说,并不会重复创建,这里只是将之前已创建的Application重新获取一下而已。

mInstrumentation.callActivityOnCreate(activity, r.state);语句的调用,标识着Activity进入onCreate流程,接下来便是Ui的绘制与展示的流程,在此便不做展开分析了。

文章的最后,我们用一个简单的图表对这一篇activity的启动流程做一个总结,并留给各位读者一个面试中高频次问题:请简述一下Activity的启动流程? 看看各位读者能不能总结归纳出一个比较好的答案。

[ActivityThread.java]
main()
attach()
   |
[ActivityManagerService.java]
attachApplication()
attachApplicationLocked()
	|		 |
	|	[ActivityThread.java]
	|	 bindApplication()			//发送了H.BIND_APPLICATION消息
	|      handleBindApplication()	                //创建Application实例,并调用onCreate方法
	|                 |
	|	  [LoadedApk.java]
	|	  makeApplication()
[ActivityTaskManagerService.java]
attachApplication()
	|
[RootActivityContainer.java]
attachApplication()
	|
[ActivityStackSupervisor.java]
realStartActivityLocked()
	|
[ClientLifecycleManager.java]
scheduleTransaction()
	|
[ClientTransaction.java]
schedule()
	|
[ActivityThread.java]
executeTransaction()
	|
[TransactionExecutor.java]
execute()
executeCallbacks()
	|
[LaunchActivityItem.java]
execute()
	|
[ActivityThread.java]
handleLaunchActivity()
performLaunchActivity()			        //创建Activity实例,调用activity attach和onCreate方法

以上就是Android10 App启动Activity源码分析的详细内容,更多关于Android10 App启动的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android10 客户端事务管理ClientLifecycleManager源码解析

    目录 正文 ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState 正文 在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程.这篇文章,我们将详细地分析framework中activity的生命周期管理功能,从更宏观的角度来更全面地了解生命周期及相关事务的工作

  • Android10 App 启动分析进程创建源码解析

    目录 正文 RootActivityContainer ActivityStartController 调用startActivityUnchecked方法 ActivityStackSupervisor 启动进程 RuntimeInit.applicationInit这个方法 正文 从前文# Android 10 启动分析之SystemServer篇 (四)中可以得知,系统在完成所有的初始化工作后,会通过 mAtmInternal.startHomeOnAllDisplays(currentU

  • Android 10 启动Init进程解析

    目录 按下电源键时,android做了啥? init进程解析 FirstStageMain SetupSelinux SecondStageMain init.rc 解析 按下电源键时,android做了啥? 当我们按下电源键时,手机开始上电,并从地址0x00000000处开始执行,而这个地址通常是Bootloader程序的首地址. bootloader是一段裸机程序,是直接与硬件打交道的,其最终目的是“初始化并检测硬件设备,准备好软件环境,最后调用操作系统内核”.除此之外,bootloader

  • Android 10 启动之servicemanager源码解析

    目录 正文 获取服务 注册服务 正文 上一篇文章: Android 10 启动分析之Init篇 (一) 在前文提到,init进程会在在Trigger 为init的Action中,启动servicemanager服务,这篇文章我们就来具体分析一下servicemanager服务,它到底做了哪些事情. servicemanager服务的源码位于/frameworks/native/cmds/servicemanager/service_manager.c,我们将从这个类的入口开始看起. int ma

  • Android10 启动Zygote源码解析

    目录 app_main ZygoteInit preload preloadClasses preloadResources preloadSharedLibraries forkSystemServer app_main 上一篇文章: # Android 10 启动分析之servicemanager篇 (二) 在init篇中有提到,init进程会在在Trigger 为late-init的Action中,启动Zygote服务,这篇文章我们就来具体分析一下Zygote服务,去挖掘一下Zygote负

  • Android10 启动之SystemServer源码分析

    目录 正文 createSystemContext startBootstrapServices startCoreServices startOtherServices 正文 上一篇文章: # Android 10 启动分析之Zygote篇 (三) 紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer. system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService.PowerManagerService

  • Android10 App启动Activity源码分析

    目录 正文 ActivityThread的main方法 Application Context对象 LaunchActivityItem ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState方法 正文 上一篇: Android 10 App启动分析之进程创建篇(一) 上一篇文章,我们探讨了App启动过程中进程创建及初始化的流程,这篇文章我们接着上篇的内容,继续探讨App的Applica

  • Hadoop源码分析六启动文件namenode原理详解

    1. namenode启动 在本系列文章三中分析了hadoop的启动文件,其中提到了namenode启动的时候调用的类为 org.apache.hadoop.hdfs.server.namenode.NameNode 其main方法的内容如下: public static void main(String argv[]) throws Exception { if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)

  • Hadoop源码分析三启动及脚本剖析

    1. 启动 hadoop的启动是通过其sbin目录下的脚本来启动的.与启动相关的叫脚本有以下几个: start-all.sh.start-dfs.sh.start-yarn.sh.hadoop-daemon.sh.yarn-daemon.sh. hadoop-daemon.sh是用来启动与hdfs相关的服务的 yarn-daemon.sh是用来启动和yarn相关的服务 start-dfs.sh是用来启动hdfs集群的 start-yarn.sh是用来启动yarn集群 start-all.sh是用

  • Netty启动流程服务端channel初始化源码分析

    目录 服务端channel初始化 回顾上一小节initAndRegister()方法 init(Channel)方法 前文传送门 Netty分布式server启动流程 服务端channel初始化 回顾上一小节initAndRegister()方法 final ChannelFuture initAndRegister() { Channel channel = null; try { //创建channel channel = channelFactory.newChannel(); //初始化

  • Netty分布式server启动流程Nio创建源码分析

    目录 NioServerSocketChannel创建 继承关系 绑定端口 端口封装成socket地址对象 跟进initAndRegister()方法 创建channel 父类的构造方法 将jdk的channel设置为非阻塞模式 前文传送门 Netty分布式Server启动流程服务端初始化源码分析 NioServerSocketChannel创建 我们如果熟悉Nio, 则对channel的概念则不会陌生, channel在相当于一个通道, 用于数据的传输 Netty将jdk的channel进行了

  • Netty分布式Server启动流程服务端初始化源码分析

    目录 第一节:服务端初始化 group方法 初始化成员变量 初始化客户端Handler 第一节:服务端初始化 首先看下在我们用户代码中netty的使用最简单的一个demo: //创建boss和worker线程(1) EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); //创建ServerBootstrap(2) ServerBootst

  • Netty源码分析NioEventLoop线程的启动

    目录 之前的小节我们学习了NioEventLoop的创建以及线程分配器的初始化, 那么NioEventLoop是如何开启的呢, 我们这一小节继续学习 NioEventLoop的开启方法在其父类SingleThreadEventExecutor中的execute(Runnable task)方法中, 我们跟到这个方法: @Override public void execute(Runnable task) { if (task == null) { throw new NullPointerEx

  • 详解SpringBoot启动代码和自动装配源码分析

    目录 一.SpringBoot启动代码主线分析 二.SpringBoot自动装配原理分析 1.自动装配的前置知识@Import 2.@SpringApplication注解分析 2.1@SpringBootConfiguration 2.2@EnableAutoConfiguration ​随着互联网的快速发展,各种组件层出不穷,需要框架集成的组件越来越多.每一种组件与Spring容器整合需要实现相关代码.SpringMVC框架配置由于太过于繁琐和依赖XML文件:为了方便快速集成第三方组件和减少

随机推荐