IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Activity 启动流程和 UML 时序图 -> 正文阅读

[移动开发]Activity 启动流程和 UML 时序图

本文以启动的目标 Activity 所属进程不存在的情形为例,结合 Android12 源码,给出了整个过程的流程图,以及局部过程的时序图。推荐一个 Android 源码阅读网站

先附上一张整体过程的流程图。app1 是当前活动的 Activity 所在的应用进程,图示为浅蓝色,app2 是即将启动的 Activity 进程,图示为深蓝色,系统进程主要为 AM(黄色) 和 WM(红色),涉及到的代码路径包括:

/frameworks/base/core/java/android/app/...
/frameworks/base/services/core/java/com/android/server/wm/...
/frameworks/base/services/core/java/com/android/server/am/...

在这里插入图片描述
如图所示,启动 Activity 过程主要分为 5 个流程,不再赘述,在后文中跳过了步骤 3 中 pause 一个 Activity 的具体流程,以及步骤 4 中 zygote fork 进程的过程,把注意力集中到了 Activity 启动过程上。

1、app1 发起 Activity 启动请求

在这里插入图片描述
比较典型的点击桌面上应用图标启动 Activity 这个场景,桌面自身也是一个 Activity,当点击事件发生后,这个 Activity 会调用到 Activity.java 的 startActivity() 方法,开始启动目标 Activity 的流程。在 Activity.java 中经过几次调用后会调用到 Instrumentain 类中的 execStartActivity() 方法。

Instrumentation 翻译为仪表盘,顾名思义,它的作用是监视 app 进程与系统间的交互,比如 Activity 和 Application 的生命周期。每个 Activity 都持有一个 Instrumentation 对象的引用,但一个应用进程只有一个 Instrumentation 对象。如下是 Instrumentation.java 中 execStartActivity 的核心逻辑:

1853      public ActivityResult execStartActivity(
1854          Context who, IBinder contextThread, IBinder token, String target,
1855          Intent intent, int requestCode, Bundle options) {
              ...
1882              int result = ActivityTaskManager.getService().startActivity(whoThread,
1883                      who.getOpPackageName(), who.getAttributionTag(), intent,
1884                      intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
1885                      requestCode, 0, null, options);
              ...
1891      }

其中,ActivityTaskManager.getService() 会获取 IActivityTaskManager 对象,它是ActivityTaskManagerService 的代理,也就是一个用于跨进程通信的 Binder。所以这里其实是跨进程调用到 WM 中 ActivityTaskManager.java 的 startActivity() 方法。

2、WM 中解析和校验启动参数、模式,处理任务栈

在这里插入图片描述
上图里跳过了 pause 当前活动 Activity 的具体过程,只以 startPausingLocked 带过。

首先,ActivityTaskManagerService.java 经过几次调用会走到如下的 startActivityAsUser() 方法。

1178      private int startActivityAsUser(IApplicationThread caller, String callingPackage,
1179              @Nullable String callingFeatureId, Intent intent, String resolvedType,
1180              IBinder resultTo, String resultWho, int requestCode, int startFlags,
1181              ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
              ...
1188          // TODO: Switch to user app stacks here.
1189          return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
1190                  .setCaller(caller)
1191                  .setCallingPackage(callingPackage)
1192                  .setCallingFeatureId(callingFeatureId)
1193                  .setResolvedType(resolvedType)
1194                  .setResultTo(resultTo)
1195                  .setResultWho(resultWho)
1196                  .setRequestCode(requestCode)
1197                  .setStartFlags(startFlags)
1198                  .setProfilerInfo(profilerInfo)
1199                  .setActivityOptions(bOptions)
1200                  .setUserId(userId)
1201                  .execute();
1202  
1203      }

其中,getActivityStartController().obtainStarter() 会通过 Starter 池获取到一个 ActivityStarter 对象,在设置 caller 的一些参数后执行 ActivityStarter 的 execute 方法。

ActivityStarter 会将 intent 和 flag 转换为 Activity 的启动逻辑,决定 Activity 如何启动,如何处理相关的任务和栈。

811      private int executeRequest(Request request) {
              ...
1177          mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1178                  request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
1179                  restrictedBgActivity, intentGrants);
              ...
1186      }

executeRequest() 会首先解析相关启动参数,然后做参数和 caller 权限的初步校验,之后调用到 startActivityUnchecked(),这个方法的作用主要是保证在启动目标 Activity 失败时能移除这个 Activity。

Here also ensures that the starting activity is removed if the start wasn't successful.

随后到了 startActivityInner(),主要进行启动模式和任务栈相关的处理。

1671      int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1672              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1673              int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1674              boolean restrictedBgActivity, NeededUriGrants intentGrants) {
                  ...
1812                  mRootWindowContainer.resumeFocusedTasksTopActivities(
1813                          mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
                  ...
1824      }

下面就到了 RootWindowContainer.java,它是窗口容器的根容器,管理了所有的窗口和显示。所以,这个类里主要进行显示相关的属性检查和处理,resumeFocusedTasksTopActivities() 方法会恢复焦点任务栈顶的 Activity。

2315      boolean resumeFocusedTasksTopActivities(
2316              Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
2317              boolean deferPause) {
                  ...
2363                  if (focusedRoot != null) {
2364                      result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
2365                  } 
                  ...
2373      }

resumeTopActivityUncheckedLocked() 用来确保栈顶 Activity 是 resumed,具体的实现逻辑在 resumeTopActivityInnerLocked 方法里。

6153      @GuardedBy("mService")
6154      private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
6155              boolean deferPause) {
              ...
6252          if (mResumedActivity != null) {
6253              ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Pausing %s", mResumedActivity);
6254              pausing |= startPausingLocked(false /* uiSleeping */, next,
6255                      "resumeTopActivityInnerLocked");
6256          }

6381          if (next.attachedToProcess()) {
                  ...
6523          } else {
                  ...
6534              mTaskSupervisor.startSpecificActivity(next, true, true);
6535          }

首先要通过 startPausingLocked() pause 栈顶 Activity,也就是暂停当前焦点所在的 Activity,然后再继续调用 startSpecificActivity() 启动目标 Activity。

下面主要关注 startSpecificActivity() 方法,它位于 ActivityTaskSupervisor 类中,这个类主要进行 ActivityStack 的管理。startSpecificActivity() 会根据要启动 Activity 目标进程状态做出不同的响应。如果进程已存在,则直接调用 realStartActivityLocked() 方法,否则会进入 startProcessAsync() 创建目标进程。

978      void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
979          // Is this activity's application already running?
980          final WindowProcessController wpc =
981                  mService.getProcessController(r.processName, r.info.applicationInfo.uid);
982  
983          boolean knownToBeDead = false;
984          if (wpc != null && wpc.hasThread()) {
985              try {
986                  realStartActivityLocked(r, wpc, andResume, checkConfig);
987                  return;
988              } catch (RemoteException e) {
989                  Slog.w(TAG, "Exception when starting activity "
990                          + r.intent.getComponent().flattenToShortString(), e);
991              }
992  
993              // If a dead object exception was thrown -- fall through to
994              // restart the application.
995              knownToBeDead = true;
996          }
997  
998          r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
999  
1000          final boolean isTop = andResume && r.isTopRunningActivity();
1001          mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
1002      }

本文是以冷启动为例,所以会有进程创建的过程,但这里省略 zygote 创建进程的具体过程,我们直接飞奔到进程创建后,会进入到 ActivityThread 中的 main 方法

3、app2 进程创建后, 执行 attach 等过程

在这里插入图片描述
首先是创建 ActivityThread 并进行 attach。在 attach 中会获取 AMS 对象,并进行跨进程调用 attachApplication 。

  @UnsupportedAppUsage
7513      private void attach(boolean system, long startSeq) {
                  ...
7521              final IActivityManager mgr = ActivityManager.getService();
7522              try {
7523                  mgr.attachApplication(mAppThread, startSeq);
7524              } catch (RemoteException ex) {
7525                  throw ex.rethrowFromSystemServer();
7526              }
           }

我们看一下实现具体逻辑的 attachApplicationLocked 方法。

4275      private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
4276              int pid, int callingUid, long startSeq) {
                  ...
4501                  thread.bindApplication(...);
                  ...
4532                  app.makeActive(thread, mProcessStats);
                  ...
4565                  didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
4534              }

(1)首先调用 ActivityThread 的 bindApplication 将主线程与应用绑定,绑定是通过 message 机制实现的,具体过程在 handleBindApplication 中完成,在这个方法中还会创建仪表盘对象、创建应用实例、回调 app 的 onCreate 生命周期。
(2)然后 makeActive 激活 app。
(3)最后通过调用到 ATMS 的 attachApplication 去启动 Activity,mAtmInternal 是一个ActivityTaskManagerService 的对象,ATMS 中并没有执行具体逻辑,似乎只是为了记录,具体还是看一下 RootWindowContainer.java。

1909      boolean attachApplication(WindowProcessController app) throws RemoteException {
...
1924                  final PooledFunction c = PooledLambda.obtainFunction(
1925                          RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
1926                          PooledLambda.__(ActivityRecord.class), app,
1927                          rootTask.topRunningActivity());
...
1940      }
942      private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
1943              WindowProcessController app, ActivityRecord top) {
...
1950              if (mTaskSupervisor.realStartActivityLocked(r, app,
1951                      top == r && r.isFocusable() /*andResume*/, true /*checkConfig*/)) {
1952                  mTmpBoolean = true;
1953              }
...
1961      }

最后,又走到了 realStartActivityLocked 方法,在这里和热启动回到同一流程。

4 真实的启动 Activity

在这里插入图片描述
首先看一下在 ActivityTaskSupervisor.java 中的 realStartActivityLocked 方法。

713      boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
714              boolean andResume, boolean checkConfig) throws RemoteException {
...
840                  // Create activity launch transaction.
841                  final ClientTransaction clientTransaction = ClientTransaction.obtain(
842                          proc.getThread(), r.appToken);
...
865                  clientTransaction.setLifecycleStateRequest(lifecycleItem);
866  
867                  // Schedule transaction.
868                  mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
948      }

该方法主要是创建事务并计划启动事务。经过一系列的调用其实会跨进程调用到 ApplicationThread 的 scheduleTransaction() 方法,ApplicationThread 是 ActivityThread 的内部类。

1004      private class ApplicationThread extends IApplicationThread.Stub {
...
1798          public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
1799              ActivityThread.this.scheduleTransaction(transaction);
1800          }
...       
          }

这里其实调用的是 ActivityThread 父类 ClientTransactionHandler 中的方法,在方法内部会发送了一个 H.EXECUTE_TRANSACTION 消息,然后通过 ActivityThread 的 handler 来处理。

2051          public void handleMessage(Message msg) {
...
2212                  case EXECUTE_TRANSACTION:
2213                      final ClientTransaction transaction = (ClientTransaction) msg.obj;
2214                      mTransactionExecutor.execute(transaction);
2215                      if (isSystem()) {
2216                          // Client transactions inside system process are recycled on the client side
2217                          // instead of ClientLifecycleManager to avoid being cleared before this
2218                          // message is handled.
2219                          transaction.recycle();
2220                      }
...
              }

我们看到,handleMessage 将流程交到了 TransactionExecutor.java 的 execute() 中处理。

69      public void execute(ClientTransaction transaction) {
... 
95          executeCallbacks(transaction);
96  
97          executeLifecycleState(transaction);
...
100      }
104      public void executeCallbacks(ClientTransaction transaction) {
...
124          final int size = callbacks.size();
125          for (int i = 0; i < size; ++i) {
...
135              item.execute(mTransactionHandler, token, mPendingActions);
136              item.postExecute(mTransactionHandler, token, mPendingActions);
...
148          }
149      }

上面代码中 item 的类型是 LaunchActivityItem, 下面看看它的 execute() 方法。

99      public void execute(ClientTransactionHandler client, IBinder token,
100              PendingTransactionActions pendingActions) {
101          Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
102          ActivityClientRecord r = client.getLaunchingActivity(token);
103          client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
104          Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
105      }

client 是一个 ClientTransactionHandler 类对象,但这个类的 handleLaunchActivity 只是一个抽象方法,具体实现在 ActivityThread.java 中。

3761      public Activity handleLaunchActivity(ActivityClientRecord r,
3762              PendingTransactionActions pendingActions, Intent customIntent) {
...
3796          final Activity a = performLaunchActivity(r, customIntent);
...

performLaunchActivity 是真正创建 Activity 的地方,然后执行 Activity 的 onCreate() 生命周期方法。

3513      private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
3536              activity = mInstrumentation.newActivity(
3537                      cl, component.getClassName(), r.intent);
...
3609                  if (r.isPersistable()) {
3610                      mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3611                  } else {
3612                      mInstrumentation.callActivityOnCreate(activity, r.state);
3613                  }
...
          }

看看 Instrumentation.java 中的 callActivityOnCreate() 方法。

1327      public void callActivityOnCreate(Activity activity, Bundle icicle) {
1328          prePerformCreate(activity);
1329          activity.performCreate(icicle);
1330          postPerformCreate(activity);
1331      }

1340      public void callActivityOnCreate(Activity activity, Bundle icicle,
1341              PersistableBundle persistentState) {
1342          prePerformCreate(activity);
1343          activity.performCreate(icicle, persistentState);
1344          postPerformCreate(activity);
1345      }

最后回到了 Activity.java 中,进行 Activity 生命周期方法的回调。

8035      final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
8048          if (persistentState != null) {
8049              onCreate(icicle, persistentState);
8050          } else {
8051              onCreate(icicle);
8052          }
...
          }

至此,Activity 创建完成。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:13:15  更:2022-04-01 00:14:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 19:24:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码