Activity
创建startActivity
请求,然后这个请求就被交给了ActivityTaskManagerService
。
这里还需要有一个概念,在Android系统每个用户有一个独立的uid.这个值从0还是.然后每个安装的包有一个独立的Uid.这个值在安装后就会固定下来,不会变.每个app启动会生成一个动态的进程id也就是pid.然后 Android系统每个用户下安装的app数量是有上限的100000个.比如用户id是0,那么安装包的uid就是从 0 - 99999. 如果用户uid=1 ,那么安装的app的uid是从 100000 - 999999.
我们来看看在Activity
调用startActivity
到ActivityTaskManagerService
都传递了哪些值过去: (这里我直接带你看Instrumentation
的execuStartActivity
方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Instrumentation{ public ActivityResult execStartActivity(Context who , IBinder contextThread , IBinder token , Activity target , Intent intent , int requestCode , Bundel options){ int result = ActivityTaskManager.getService().startActivity(contextThread, who.getOpPackageName(), who.getAttributionTag(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); } } class ActivityTaskManagerService{ public final int startActivity(IApplicationThread caller, String callingPackage, String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return } }
|
参数解释:
Instrumentation.execStartActivity:
- IBinder contextThread : 是ActivityThread 的 ApplicationThread对象, ApplicationThread连接了App进程和系统服务间进行的通信.也就是跨进程通信.
- IBinder token : 是当前调用startActivity的Activity的IBinder值. 每个Activity都一个叫mToken的成员变量,他保存的就是IBinder
- Activity target : 是当前调用startActivity的Activity对象
- Intent intent : 这个就是我们在startActivity时候新建的Intent对象
ActivityTaskManagerSercice.startActivity:
- IApplicationThread caller : 调用startActivity者的ApplicationThread对象,用来实现两个进程间的通信.
- Srting callingPackage : 调用者所属的包
- Intent intent : 调用者创建的Intent
- IBindet resultTo : 调用startActivity的Activity的IBinder对象.通过这个resuleTo可以找到调用者是谁.
总结: 上面最终的参数就是intent 和 token , 通过intent可以知道目标Activity是谁 , 通过token 可以知道调用者是谁.
接着来到ActivityTaskManagerService
的startActivtyAsUser
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
| class ActivityTaskManagerService{ private int startActivityAsUser(IApplicationThread caller, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { assertPackageMatchesCallingUid(callingPackage);
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return getActivityStartController().obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setCallingFeatureId(callingFeatureId) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setUserId(userId) .execute();
} }
|
然后会先判断应用是否属于当前用户组的应用,如果不是就不给启动,然后如果通过验证.就会去构建一个ActivityStarter
,然后会将启动的各种值写入到ActivityStarter
的Request
的成员变量里面.(这里用到了构造者模式) 然后执行execute
进行启动.
1 2 3 4 5 6 7 8 9 10 11 12
| class ActivityStarter{ int execute(){ final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo); launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mRequest.intent, caller, callingUid); final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); res = executeRequest(mRequest); } }
|
首先第一步通过token
值去获取他对应的ActivityRecord
对象,这里我们需要知道每一个Activity
都有对应他的ActivityRecord
对像.
来看下是如何通过Token就能获取到ActivityRecord的:
1 2 3 4 5 6 7 8
| ActivityRecord.forTokenLocked(mRequest.resultTo);
class ActivityRecord{ static ActivityRecord forTokenLocked(IBinder token){ return Token.toTokenActivityRecordLocked((Token)token); } }
|
这里可以看到他将Binder
强转成了Token
对象了.为什么可以强转,那就要看下Token这个类:
1 2 3 4 5 6
| class Token extends IApplicationToken.Stub{ static ActivityRecord tokenToActivityRecordLocked(Token token){ ActivityRecord r = token.weakActivity.get(); return r; } }
|
因为Token
就是IBinder
的子类,所以可以进行强转.
关于Activity的 mToken:IBinder 值是什么时候传递的这个后面分析
在Android系统中,Activity的生命周期都是由ActivityTaskManagerService来管理的,每个Activity在AMS中都有一个唯一的Token来表示自己.
在ActivityTaskManagerService
里面创建了RootWindowContainer
对象,是怎么创建的呢?
1 2 3 4 5 6 7 8 9
| class ActivityTaskManagerService{ RootWindowContainer mRootWindowContainer; public void setWindowManager(WindowManagerService wm) { synchronized (mGlobalLock) { mWindowManager = wm; mRootWindowContainer = wm.mRoot; } } }
|
RootWindowContainer 是 Android系统中的顶层窗口容器,他负责管理所有窗口的层级关系.然后每个层级的窗口显示顺序是由 WindowManagerService控制的. 详见博客 < < RootWindowContainer > >
接着看第三步: executeRequest
代码:
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
| class ActivityStarter{ int executeRequest(Request request){ final IBinder resultTo = request.resultTo; final IApplicationThread caller = request.caller; WindowProcessController callerApp = null; callerApp = mService.getProcessController(caller); ActivityRecord sourceRecord = null; ActivityRecord resultRecord = null; if (resultTo != null) { sourceRecord = mRootWindowContainer.isInAnyTask(resultTo); } ActivityStartInterceptor mInterceptor; if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, callingPid, callingUid, checkedOptions)) { intent = mInterceptor.mIntent; }
ActivityRecord r = new ActivityRecord.Builder(mService) .setCaller(callerApp) .setLaunchedFromPid(callingPid) .setLaunchedFromUid(callingUid) .setLaunchedFromPackage(callingPackage) .setLaunchedFromFeature(callingFeatureId) .setIntent(intent) .setResolvedType(resolvedType) .setActivityInfo(aInfo) .setConfiguration(mService.getGlobalConfiguration()) .setResultTo(resultRecord) .setResultWho(resultWho) .setRequestCode(requestCode) .setComponentSpecified(request.componentSpecified) .setRootVoiceInteraction(voiceSession != null) .setActivityOptions(checkedOptions) .setSourceRecord(sourceRecord) .build(); startActivityUnchecked() } private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants) { activityTaskManagerService.deferWindowLayout(); result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants); mService.continueWindowLayout(); } int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, Task inTask, boolean restrictedBgActivity, NeededUriGrants intentGrants){ final Task reusedTask = getReusableTask(); final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask(); final boolean newTask = targetTask == null; if (newTask) { final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.getTask() : null; setNewTask(taskToAffiliate); } else if (mAddingToTask) { addOrReparentStartingActivity(targetTask, "adding to task"); } mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, mStartActivity.getUriPermissionsLocked()); mRootWindowContainer.startPowerModeLaunchIfNeeded( false , mStartActivity); } private Task mTargetRootTask; mTargetRootTask.startActivityLocked(mStartActivity, topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask, mKeepCurTransition, mOptions, sourceRecord); }
|
在android12上,Handler会发送一个EXECUTE_TRANSACTION
的Message
消息。消息内容ClientTransaction
。我们看下这个类:
1 2 3 4
| case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); break;
|
1 2 3 4 5
| class ClientTransaction{
private ActivityLifecycleItem mLifecycleStateRequest;
}
|
ClientTransaction
内部有个ActivityLifecycleItem
的成员变量,这个类是抽象类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public abstract class ActivityLifecycleItem extends ActivityTransactionItem { @IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = { UNDEFINED, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_RESTART }) @Retention(RetentionPolicy.SOURCE) public @interface LifecycleState{} 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
的生命周期.
所以这里倒着往回找,找下每个生命周期是怎么触发的,然后ClientTransaction
对象是什么时候创建的.
巴拉巴拉…..
过程太过于复杂,这里我直接用语言描述:
在 Activity 触发 startActivity 方法后, 会进入到 system_server进程,然后调用 ActivityTaskManagerService 的 startActivity 方法, 会将构建的 intent ,当前 Activity 的 token 传入到 ActivityTaskManagerService 内, 然后 ActivityTaskManagerService 会构建 ActivityStarter对象,然后创建 Request 将请求的信息放入到 Request里面, 然后执行了 Request.execute() 方法. 接着会判断当前要启动的app是不是属于当前用户组的,在 android 里面每个用户组拥有的资源是有上限制的10000个. 接着会为我们要启动的 Activity 构建 ActivityRecord 对象, 然后会判断当前 Activity 的启动模式, 如果是 singleInstance 的话,必定会创建新Task,但如果设置了Intent.FLOAG_ACTIVITY_NEW_TASK
,但是taskAffinity
没有设置不同的值的话,还是不会创建新的Task
的. 接着在 TASk 里面会触发 ClientLifeCycleManager.scheduleTransaction() 然后会调用 ApplicationThread.scheduleTransaction()方法,实现从系统进程到用户进程的调用.然后就回到了用户进程,然后完成整个Activity的调用.
回顾整个启动流程,我似乎发现 Activity的启动没有那么复杂,主要就做了这么几件事情,Activity调用startActivity方法,然后将事情交给了ActivtiyTaskManagerService, ActivityTaskMangerService的作用就是用来判断要启动的Acvitiy是不是属于当前用户组,是否有权限,然后判断进程是否要创建,task是否要创建,activtity要放入那个task里面,管理着activity的生命周期.用户进程只需要关心页面怎么展示就行.