广告位联系
返回顶部
分享到

Android10 App启动Activity源码分析

Android 来源:互联网 作者:佚名 发布时间:2022-10-11 21:25:19 人浏览
摘要

ActivityThread的main方法 让我们把目光聚焦到ActivityThread的main方法上。 ActivityThread的源码路径为/frameworks/base/core/java/android/app/ActivityThread。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

ActivityThread的main方法

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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方法往下追踪。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

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);

    }

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

1

2

3

4

5

6

7

8

9

10

11

12

13

@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);

      }

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

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;

   }

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

1

2

3

4

5

6

7

8

9

10

11

12

13

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中找到这条消息的代码段。

1

2

3

4

5

6

7

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;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

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。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

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;

   }

1

2

3

4

5

6

7

8

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的创建与初始化已经至此结束,接下来我们将目光放到ActivityTaskManagerInternal的attachApplication方法。

1

2

3

4

5

public boolean attachApplication(WindowProcessController wpc) throws RemoteException {

           synchronized (mGlobalLockWithoutBoost) {

               return mRootActivityContainer.attachApplication(wpc);

           }

       }

进入了RootActivityContainer中继续执行。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

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;

   }

由ActivityStackSupervisor的realStartActivityLocked方法去真正准备启动Activity。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

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及其一系列相关的类。

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

LaunchActivityItem

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

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

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

1

2

3

4

5

6

7

8

9

10

11

@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类,在这个类中定义了一系列的生命周期状态,具体如下:

1

2

3

4

5

6

7

8

9

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为步长递增定义。为什么这么设计,我们后续会讲到。

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

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

ClientLifecycleManager

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

1

2

3

4

5

6

7

8

9

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();

        }

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

ClientTransaction

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

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

1

2

3

public void schedule() throws RemoteException {

     mClient.scheduleTransaction(this);

 }

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

1

2

3

4

5

public void executeTransaction(ClientTransaction transaction) {

        transaction.preExecute(this);

        getTransactionExecutor().execute(transaction);

        transaction.recycle();

    }

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

1

2

3

4

5

6

7

8

9

10

11

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);

      }

  }

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

TransactionExecutor

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

1

2

3

4

5

6

public void execute(ClientTransaction transaction) {

       ...

       executeCallbacks(transaction);

       executeLifecycleState(transaction);

       mPendingActions.clear();

   }

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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方法:

1

2

3

4

5

6

7

8

9

10

11

12

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数组。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

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继续往下追踪:

1

2

3

4

5

public Activity handleLaunchActivity(ActivityClientRecord r,

     ...

       final Activity a = performLaunchActivity(r, customIntent);

     ...

   }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

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方法里看一下,第一句话就解释了原因:

1

2

3

if (mApplication != null) {

          return mApplication;

      }

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

[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方法


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7088189240269340685
相关文章
  • Kotlin的Collection与Sequence操作异同点介绍

    Kotlin的Collection与Sequence操作异同点介绍
    在Android开发中,集合是我们必备的容器,Kotlin的标准库中提供了很多处理集合的方法,而且还提供了两种基于容器的工作方式:Collection 和
  • 实现一个Kotlin函数类型方法

    实现一个Kotlin函数类型方法
    接口与函数类型 业务开发中,经常会有实现一个函数式接口(即接口只有一个方法需要实现)的场景,大家应该都会不假思索的写出如下代
  • Android10 App启动Activity源码分析
    ActivityThread的main方法 让我们把目光聚焦到ActivityThread的main方法上。 ActivityThread的源码路径为/frameworks/base/core/java/android/app/ActivityThread。 1 2
  • Android10客户端事务管理ClientLifecycleManager源码解析

    Android10客户端事务管理ClientLifecycleManager源码解析
    在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程。这
  • Kotlin对象的懒加载方式by lazy与lateinit异同介绍

    Kotlin对象的懒加载方式by lazy与lateinit异同介绍
    属性或对象的延时加载是我们相当常用的,一般我们都是使用 lateinit 和 by lazy 来实现。 他们两者都是延时初始化,那么在使用时那么他们两
  • Android类加载流程分析

    Android类加载流程分析
    本文分析的代码基于Android8.1.0源码。 流程分析 从loadClass开始,我们来看下Android中类加载的流程 /libcore/ojluni/src/main/java/java/lang/ClassLoader.ja
  • Android实现读写USB串口数据的代码

    Android实现读写USB串口数据的代码
    最近在研究USB方面的内容;先后做了关于Android读写HID、串口设备的DEMO。本文比较简单,主要介绍的是Android实现读取串口数据的功能 废话不
  • Epoxy - 在RecyclerView中构建复杂界面
    Diffing 对于复杂数据结构支持的多个视图类型展示在屏幕上, Epoxy此时是尤其有用的. 在这些场景中, 数据可能会被网络请求, 异步 Observable, 用
  • Android性能优化的详细介绍

    Android性能优化的详细介绍
    性能优化是一个app很重要的一部分,一个性能优良的app从被下载到启动到使用都能给用户到来很好的体验。自然我们做性能优化也是从被下
  • Android进阶宝典-插件化2(Hook启动插件中四大组件

    Android进阶宝典-插件化2(Hook启动插件中四大组件
    在上一节,我们主要介绍了如果通过反射来加载插件中的类,调用类中的方法;既然插件是一个apk,其实最重要的是启动插件中的Activity、
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计