根Activity的启动过程简述

2018-02-27  本文已影响116人  passerbywhu

参照《Android系统源代码情景分析》中的例子。

有三个Activity:

1. MainActivity 根Activity

2.SubActivityInProcess  与根Activity运行在同一个进程的Activity

3.SubActivityInNewProcess 运行在新进程中的Activity

两个重要的结构体:

1.ActivityRecord 每个启动的Activity在ActivityManagerService中都有唯一一个对应的ActivityRecord对象。该对象是Binder本地对象。同时Activity所在的ActivityThread会持有该ActivityRecord的binder代理对象。在Activity和ActivityManagerService进行远程通信的时候,该binder代理对象会被传输以被ActivityManagerService用来识别当前与自己通信的Activity的具体信息。

2.ApplicationThread 每个app都含有这样一个Binder本地对象。每个运行的app进程在ActivityManagerService中都有一个唯一的ProcessRecord对象。该对象保存了ApplicationThread的Binder代理对象。从而ActivityManagerService可以主动与Activity所在的进程进行通信。

3.ActivityClientRecord 每个启动的Activity在自身进程中都有唯一一个对应的ActivityClientRecord对象。它和Activity进程所持有的ActivityManagerService中的ActivityRecord的代理对象是一一对应的。

重要变量:

ActivityStack类有三个成员变量mResumedActivity, mLastPausedActivity和mPausingActivity,它们的类型均为ActivityRecord,分别用来描述系统当前激活的Activity组件、上一次被中止的Activity组件,以及正在被中止的Activity组件。

从Launcher启动MainActivity

1.Launcher-->startActivitySafely

2.Activity-->startActivity

3.Activity-->startActivityForResult

Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(

    this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode

);

mMainThread.getApplicationThread()就是Launcher Activity所属进程的ApplicationThread本地对象。

mToken是Launcher Activity在ActivityManagerService中的ActivityRecord对应的代理对象。

4.Instrumentation-->execStartActivity

5.ActivityManagerProxy-->startActivity

将需要启动的intent信息以及自身的一些信息写入Parcel中进行远程通信

...

//caller是IApplicationThread

data.writeStrongBinder(caller != null ? caller.asBinder() : null);

//intent是需要启动的MainActivity的相关信息

intent.writeToParcel(data, 0);

//resultTo是Launcher Activity对应的ActivityRecord代理对象

data.writeStrongBinder(resultTo);

mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

...

接下来在ActivityManagerService进程中执行

6.ActivityManagerService-->startActivity

7.ActivityStack-->startActivityMayWait

通过PackageManager解析需要启动的intent信息,获取对应的ActivityInfo

ActivityInfo aInfo;

ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS);

aInfo = rInfo != null ? rInfo.activityInfo : null;

8.ActivityStack-->startActivityLocked

通过Launcher传过来的ActivityRecord代理对象获取其在ActivityManagerService中对应的ActivityRecord  sourceRecord

通过Launcher传过来的IApplicationThread对象获取Launcher进程在ActivityManagerService中对应的ProcessRecord对象 callerApp,以及进程id callingPid和用户id  callingUid。

用callerApp callingUid以及第7步得到的aInfo构造需要启动的MainActivity对应的ActivityRecord r。

9. ActivityStack-->startActivityUncheckedLocked

检测到MainActivity所在的Task不存在,新建一个TaskRecord。将该TaskRecord赋给MainActivity对应的ActivityRecord的task变量中。并将该TaskRecord加入到ActivityManagerService的recentTask中。

   ActivityStack-->startActivityLocked

将MainActivity对应的ActivityRecord加入到ActivityStack的mHistory中。

10.ActivityStack.resumeTopActivityLocked

获取当前运行的top Activity的ActivityRecord(就是MainActivity)。和mResumedActivity(即Launcher Activity)相比较。发现不一致。于是需要告诉mResumedActivity需要执行pause操作。

11.ActivityStack-->startPausingLocked

通过Launcher Activity对应的ActivityRecord所保存的ProcessRecord的thread对象获取Launcher Activity所在进程的IApplicationThread代理对象。从而进行远程通信。

//prev是Launcher Activity对应的ActivityRecord。 app是ProcessRecord类型。thread是IApplicationThread类型。

prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, prev.configChangFlags);

同时发送一个PAUSE_TIMEOUT_MSG延迟消息。如果PAUSE_TIMEOUT时间之后这个消息没有被取消掉,说明Launcher Activity的pause操作无响应了。

12.ApplicationThreadProxy.schedultePauseActivity

...

//token是Launcher Activity对应的ActivityRecord

data.writeStrongBinder(token)

mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);

...

接下来在Launcher Activity的进程中执行

13.ApplicationThread-->schedulePauseActivity

14.ActivityThread-->queueOrSendMessage

15.H-->handleMessage

16.ActivityThread-->handlePauseActivity

//token是Launcher Activity的ActivityRecord代理对象。

Bundle state = performPauseActivity(token, finished, true);

17. ActivityManagerProxy-->activityPaused

...

//token是Launcher Activity的ActivityRecord代理对象

data.writeStrongBinder(token);

data.writeBundle(state);

mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);

...

接下来在ActivityManagerService进程中执行

18.ActivityManagerService-->activityPaused

19.ActivityStack-->activityPaused

移除之前发送的PAUSE_TIMEOUT_MSG延时信息

修改Launcher Activity的ActivityRecord的状态。

int index = indexOfTokenLocked(token);

ActivityRecord r = mHistory.get(index);

20. ActivityStack-->completePauseLocked

将mPausingActivity置为null

21.ActivityStack-->resumeTopActivityLocked

上一次进入这个函数的时候由于resumedActivity不等于top running Activity.所以进入了pause流程。

这次由于已经pause过了。所以直接进入start流程。

22.ActivityStack-->startSpecificActivityLocked

检测到MainActivity对应的进程并没有起来。也即MainActivity对应的ActivityRecord的app (ProcessRecord类型)以及app.thread(IApplicationThread类型)为null。启动进程。

23.ActivityManagerService.startProcessLocked

为MainActivity所在进程创建ProcessRecordLocked对象。启动进程

int[] gids = mContext.getPackageManager().getPackageGids(app.info.packageName);

int pid = Process.start("android.app.ActivityThread", mSimpleProcessManageMent ? app.processName : null, uid, uid, gids, debugFlags, null);

发送一个延时消息PROC_START_TIMEOUT_MSG,如果PROC_START_TIMEOUT之后,该消息没有被取消。则判断为启动进程无响应。

接下来在MainActivity的进程中运行

24.ActivityThread-->main

创建ActivityThread。创建ApplicationThread。

25.ActivityManagerProxy-->attachApplication

//app是IApplicationThread类型

data.writeStrongBinder(app.asBinder());

mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);

接下来在ActivityManagerService的进程中运行

26.ActivityManagerService.attachApplication

27.ActivityManagerService.attachApplicationLocked

通过Binder驱动告知的pid获取当前attach的进程在ActivityManagerService中对应的ProcessRecord。第23步创建的。

将ApplicationThread代理对象保存在ProcessRecord中。供之后ActivityManagerService与Activity进程通信用。

移除之前发送的延迟消息PROC_START_TIMEOUT_MSG

检测到top running Activity需要运行,且其ActivityRecord的app为null,且进程名等于当前attach的进程名。于是启动MainActivity.

28.ActivityStack.realStartActivityLocked

ProcessRecord有activities变量保存有所有在该进程中运行的Activity

29.ApplicationThreadProxy-->scheduleLaunchActivity

...

//intent是MainActivity的intent

intent.writeToParcel(data, 0);

//token是MainActivity对应的ActivityRecord本地对象

data.writeStrongBinder(token);

//info是MainActivity对应的ActivityInfo

info.writeToParcel(data, 0);

mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);

...

接下来是在MainActivity的进程中运行的

30.ApplicationThread-->scheduleLaunchActivity

为MainActivity创建ActivityClientRecord。将其和ActivityRecord关联起来。

31.ActivityThread-->queueOrSendMessage

32.H-->handleMessage

调用ActivityThread类的getPackageInfoNoCheck获取LoadedApk对象。赋给ActivityClientRecord的packageInfo成员变量中。

33.ActivityThread-->handleLaunchActivity

34.ActivityThread.performLaunchActivity

调用Instrumentation.newActivity创建MainActivity的实例。

创建MainActivity的Application。

为MainActivity的实例赋予需要用到的变量。

35.MainActivity.onCreate

上一篇下一篇

猜你喜欢

热点阅读