自由笔记-Activity之启动流程分析

本文详细剖析了Android中Activity的启动流程,从客户端的startActivity到ActivityManagerService的处理,再到ActivityThread的调度,涉及binder通信、ActivityRecord、TaskRecord等关键概念。解析了包括启动新Activity、进程管理、生命周期回调在内的多个步骤,揭示了系统如何管理和启动Activity的复杂逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Activity框架和管理结构

Activity管理的核心是AcitivityManagerService,是一个独立的进程;

ActiveThread是每一个应用程序所在进程的主线程,循环的消息处理;

ActiveThread与AcitivityManagerService的通信是属于进程间通信,使用binder机制,通过ApplicationThread这个桥梁进行通信

ApplicationThread是ActivityThread的一个内部类

一个应用程序中所有Activity只有一个ActivityThread属于一个Process

 

ActiveThread重要成员介绍:

final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();//activity记录类

final ApplicationThread mAppThread = new ApplicationThread();用来与AMS交互通信的桥梁,是一个binder.

final H mH = new H();消息循环handler。

Instrumentation mInstrumentation;用于监控程序和系统之间的交互操作

 

 

ActivityManagerService:Activity管理服务类,通过mHistory栈来管理所有的activity,应用启动activity之后,发动启动请求到AMS,AMS会根据

activity、ProcessRecord等信息创建HistoryRecord实例r并加入到mHistory当中。activity被加入到mHistory之后,只是说明在服务端可以找到该

activity记录了,但是在客户端目前还没有该activity记录。还需要通过ProcessRecord中的thread(IApplication)变量,调用它的

scheduleLaunchActivity方法在ActivityThread中创建新的ActivityRecord记录(之前我们说过,客户端的activity是用ActivityRecord

记录的,并放在mActivities中)

app.thread.scheduleLaunchActivity(new Intent(r.intent), r,System.identityHashCode(r),

 

ActivityRecord:activity记录类,代表一个Activity。

 

TaskRecord:任务栈记录类,代表一个存放activity的任务栈

 

ActivityStarter:activity启动前逻辑处理类,主要收集所有的逻辑来确定意图(intent)和标志(flag),然后转变为对应的活动(activity)和关联的任务和堆栈

 

ActivityStack:activtiy任务栈管理类,维护着一个private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();负责管理各个activity的任务栈

 

ActivityStackSupervisor:任务栈超级管理员,其实算ActivityStack的辅助管理类,它和ActivityStack相互持有

 

系统启动的时候,会创建一个PackageManagerService,PackageManagerService会对应用程序的配置文件AndroidManifest.xml进行解析,从而得到程序里的组件信息。

PackageManagerService去查询所有action为“android.intent.action.MAIN”并且category为“android.intent.category.LAUNCHER”的Activity,然后为每个

应用程序创建一个快捷方式图标,并把程序信息与之关联,作为启动的第一个Activity。

 

我将activty启动分为以下几步:

1、客户端发出启动activity命令;

2、AMS接受到命令,启动Activity相关工作

3、AMS查询当前需要启动activity的任务栈是否有需要执行onPasue的activity,如果有执行,如果没有启动activity

4、如果有需要执行onPause的activity,那么回调客户端调用该方法

5、该方法调用完成后,通知AMS启动需要启动的activity

6、需要启动的activity准备信息完成后,判断该activity所属进程是否已经启动,如果启动,直接启动activity,如果没有,先启动进程,进入到该进程的activityThread的main方法

7、AMS启动activity,通知客户端,调用app.thread.scheduleLaunchActivity

8、客户端执行scheduleLaunchActivity,进行activity的一系列启动动作:生命周期方法执行、设置视图、通知WMS绘制视图

9、activity成功启动后,通知AMS让需要执行onStop方法的activity执行该方法

 

其中1-7步主要在AMS部分执行

第8步在客户端执行

第9步在AMS执行

 

AMS部分:

 

1、不管是从lancher启动还是应用内启动,最原始的起点,都是activity内部的startActivity方法

 

@Override

public void startActivity(Intent intent, @Nullable Bundle options) {

if (options != null) {

startActivityForResult(intent, -1, options);

} else {

startActivityForResult(intent, -1);

}

}

参数requestCode=-1表示不需要把结果传送回来。

 

然后进入到Instrumentation的execStartActivity方法,然后会调用

int result = ActivityManagerNative.getDefault()

.startActivity(whoThread, who.getBasePackageName(), intent,

intent.resolveTypeIfNeeded(who.getContentResolver()),

token, target != null ? target.mEmbeddedID : null,

requestCode, 0, null, options);

进入到AMS中的startActivity方法中

 

2、AMS中的startActivity的方法线

startActivity->startActivityAsUser->mActivityStarter.startActivityMayWait

 

3、进入到ActivityStarter,对Intent进行分析处理

startActivityMayWait->startActivityLocked->startActivityUnchecked->ActivityStack.startActivityLocked->ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

 

在Starter的startActivityLocked方法中,有一个非常重要的地方,就是创建了一个ActivityRecord,表示一个Activity的所有信息

ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,

intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,

requestCode, componentSpecified, voiceSession != null, mSupervisor, container,

options, sourceRecord);

在这个ActivityRecoder中,我们有一点要记住,它创建了一个 appToken = new Token(this, service);

它是一个static class Token extends IApplicationToken.Stub,代表着这个Activity,这个Token最终是和WMS交互的身份校验符

 

接下来进入startActivityUnchecked方法,这里主要做一些启动前的任务栈、Activity状态的初始化工作,

然后进入到ActivityStack.startActivityLocked将token传递给WMS

最后进入到ActivityStackSupervisor.resumeFocusedStackTopActivityLocked方法

 

4、进入到ActivityStack的startActivityLocked方法,将刚刚生成的token传递给WMS

startActivityLocked->addConfigOverride->mWindowManager.addAppToken(......);

 

5、进入到ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

resumeFocusedStackTopActivityLocked->ActivityStack.resumeTopActivityUncheckedLocked->ActivityStack.resumeTopActivityInnerLocked

 

resumeTopActivityInnerLocked这个方法是启动前的最终检查,这里会有一个判断:

if (mResumedActivity != null) {

if (DEBUG_STATES) Slog.d(TAG_STATES,

"resumeTopActivityLocked: Pausing " + mResumedActivity);

pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);

}

if (pausing) {

if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,

"resumeTopActivityLocked: Skip resume: need to start pausing");

// At this point we want to put the upcoming activity's process

// at the top of the LRU list, since we know we will be needing it

// very soon and it would be a waste to let it get killed if it

// happens to be sitting towards the end.

if (next.app != null && next.app.thread != null) {

mService.updateLruProcessLocked(next.app, true, null);

}

if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();

return true;

}

如果任务栈顶的Activity不为null,那么执行上一个activity的onPasuse方法,然后返回,该方法到此为止

如果没有执行onPause方法的activity,又会进行下一个判断:

if (next.app != null && next.app.thread != null) {

......

}else{

mStackSupervisor.startSpecificActivityLocked(next, true, true);

}

这里很好理解,如果要启动的activity已经创建过了,那么再次把它放到栈顶,会执行onRestart方法然后走对应的生命周期

如果没有那么进入到mStackSupervisor.startSpecificActivityLocked方法来创建一个新的activity。这里我们先不分析,我们先分析onPause这条线,最后也会走到mStackSupervisor.startSpecificActivityLocked这里来的

 

6、进入到ActivityStack.startPausingLocked方法

首先会执行completePauseLocked

在ActivityStack.completePauseLocked的方法中,有一个判断当上一个activity不可见了,是pause状态,那么执行addToStopping方法

if (!mStackSupervisor.mStoppingActivities.contains(r)) {

mStackSupervisor.mStoppingActivities.add(r);

}

将该activity加入到mStoppingActivities集合中,等待调用onStop方法

if (prev.app != null && prev.app.thread != null) {

if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);

try {

EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,

prev.userId, System.identityHashCode(prev),

prev.shortComponentName);

mService.updateUsageStats(prev, false);

prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,

userLeaving, prev.configChangeFlags, dontWait);

} catch (Exception e) {

// Ignore exception, if process died other code will cleanup.

Slog.w(TAG, "Exception thrown during pause", e);

mPausingActivity = null;

mLastPausedActivity = null;

mLastNoHistoryActivity = null;

}

}

这里可以看出,如果栈顶activity确实存在,并且进程没有死掉,那么会回调它的schedulePauseActivity方法,至此,我们回到客户端的ActivityThread.ApplicationThread中

 

7、ApplicationThread.schedulePauseActivity方法

发送了一个PAUSE_ACTIVITY的message,然后进入到handlePauseActivity方法

handlePauseActivity->performPauseActivity->performPauseActivityIfNeeded->mInstrumentation.callActivityOnPause(r.activity)->activity.performPause();

至此,上一个activity的onPause方法执行

if (!dontReport) {

try {

ActivityManagerNative.getDefault().activityPaused(token);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

}

至此,我们又回到了AMS中的activityPaused方法

 

8、AMS的activityPaused方法

activityPaused->ActivityStack.activityPausedLocked->ActivityStack.completePauseLocked

然后又调用了mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);

我们又进入到了ActivityStackSupervisor.resumeFocusedStackTopActivityLocked的方法,

 

9、又进入到ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

resumeFocusedStackTopActivityLocked->ActivityStack.resumeTopActivityUncheckedLocked->ActivityStack.resumeTopActivityInnerLocked

再次进入该方法后,之前的pause方法那里会跳过,会根据获取到的栈顶activity next的状态来判断:

如果没有执行onPause方法的activity,又会进行下一个判断:

if (next.app != null && next.app.thread != null) {

......

}else{

mStackSupervisor.startSpecificActivityLocked(next, true, true);

}

这里很好理解,如果要启动的activity已经创建过了,那么再次把它放到栈顶,会执行onRestart方法然后走对应的生命周期

如果没有那么进入到mStackSupervisor.startSpecificActivityLocked方法来创建一个新的activity。

所以,接下来进入到mStackSupervisor.startSpecificActivityLocked方法

 

10、进入到startSpecificActivityLocked方法

ProcessRecord app = mService.getProcessRecordLocked(r.processName,

r.info.applicationInfo.uid, true);

首先获取到该activity所属的进程,判断该activity的进程是否已经启动,如果已经启动进入startSpecificActivityLocked方法回调客户端的app.thread.scheduleLaunchActivity方法

如果该activity的进程没有启动,那么启动进程

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

"activity", r.intent.getComponent(), false, false, true);

我们这里重点分析启动进程的这一块,因为这一块最后也会进入到app.thread.scheduleLaunchActivity方法

 

11、启动进程后,会执行客户端的ActivityThread的main方法。

Looper.prepareMainLooper();

ActivityThread thread = new ActivityThread();

thread.attach(false);

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

Looper.loop();

在Main方法中,开启UI线程消息队列循环,新建ActivityThread对象,执行ActivityThread的attach方法

attach函数主要通过binder机制与AMS进行通信,它主要做了:

将ApplicationThread与ActivityManager进行绑定

final IActivityManager mgr = ActivityManagerNative.getDefault();

try {

mgr.attachApplication(mAppThread);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

通过调用AMS的代理attachApplication方法来实现。这样在AMS中建立了app进程ProcessRecord的信息,通过这个ProcessRecord就可以回调

ApplicationThread中的方法来启动app进程中的activity。

 

11、在AMS中,先调用了attachApplication方法,

attachApplication->attachApplicationLocked->mStackSupervisor.attachApplicationLocked

在attachApplicationLocked方法中,进行了application的绑定:thread.bindApplication(......)

handleBindApplication方法里面做了两件事:

1、创建Instrumentation

2、在LoadedApk中创建Application app = data.info.makeApplication(data.restrictedBackupMode, null);在ActivityThread中赋值给mInitialApplication;

我们来看makeApplication方法:

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);

创建ContextImpl并赋值给Application,这个ContextImpl就是Application的mBase变量,也就是getBaseContext所获取的值,在Context专题中会讲到,在Activity也会遇到它

不管是Activity还是Application中去调用getApplicationContext,最后都会调用

@Override

public Context getApplicationContext() {

return (mPackageInfo != null) ?

mPackageInfo.getApplication() : mMainThread.getApplication();

}

mPackageInfo.getApplication()或者mMainThread.getApplication()都指向刚刚创建的application

 

然后调用了mStackSupervisor.attachApplicationLocked(app)方法。在该方法中会调用realStartActivityLocked(hr, app, true, true)方法。

在该方法中又会调用app.thread.scheduleLaunchActivity方法回到activityThread中启动activity。

 

 

客户端部分:

 

12、scheduleLaunchActivity->handleLaunchActivity->performLaunchActivity->handleResumeActivity

在scheduleLaunchActivity方法里面会创建一个ActivityClientRecord r = new ActivityClientRecord();对象它对应着AMS的ActivityRecord

在与AMS绑定了之后,AMS会最终会调用ApplicationThread的scheduleLaunchActivity方法,该方法会用H发送一个 sendMessage(H.LAUNCH_ACTIVITY, r);消息

在H中,接受到消息之后,会调用 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");方法

 

首先调用performLaunchActivity生成Activity实例,并对其参数进行初始化,这里包括

1、创建activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

2、如果application没有创建或者启动,创建

3、创建ContextImpl Context appContext = createBaseContextForActivity(r, activity);

4、执行activity.attach方法,设定mBase为刚刚创建的ContextImpl,创建mWindow = new PhoneWindow(this, window);设定window的回调为自身,设定window的windowManager

5、执行声明周期函数onCreate,mInstrumentation.callActivityOnCreate,执行onStart方法activity.performStart();

最后将activity存放到集合中,mActivities.put(r.token, r);

 

接下来进入handleResumeActivity方法

首先执行performResumeActivity方法,执行activity的onResume方法 r.activity.performResume();

 

执行完相关生命周期函数之后,handleResumeActivity方法里开始进行窗口绑定,将activity显示到窗口上。

r.window = r.activity.getWindow();

View decor = r.window.getDecorView();

decor.setVisibility(View.INVISIBLE);

ViewManager wm = a.getWindowManager();

WindowManager.LayoutParams l = r.window.getAttributes();

a.mDecor = decor;

l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

l.softInputMode |= forwardBit;

if (r.mPreserveWindow) {

a.mWindowAdded = true;

r.mPreserveWindow = false;

// Normally the ViewRoot sets up callbacks with the Activity

// in addView->ViewRootImpl#setView. If we are instead reusing

// the decor view we have to notify the view root that the

// callbacks may have changed.

ViewRootImpl impl = decor.getViewRootImpl();

if (impl != null) {

impl.notifyChildRebuilt();

}

}

if (a.mVisibleFromClient && !a.mWindowAdded) {

a.mWindowAdded = true;

wm.addView(decor, l);

}

 

 

13、当activity成功启动,并且执行完生命周期函数后,继续通知AMS执行之前activity的onStop方法

Looper.myQueue().addIdleHandler(new Idler());

在最后会往消息队列里面传递一个闲时任务,这个任务会调用AMS的方法

am.activityIdle(a.token, a.createdConfig, stopProfiling);

activityIdle->mStackSupervisor.activityIdleInternalLocked->stack.stopActivityLocked

ActivityRecord r =mStackSupervisor.activityIdleInternalLocked(token, false, config);

for (int i = 0; i < NS; i++) {

r = stops.get(i);

final ActivityStack stack = r.task.stack;

if (stack != null) {

if (r.finishing) {

stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);

} else {

stack.stopActivityLocked(r);

}

}

}

如果是销毁掉的activity,执行finishCurrentActivityLocked,如果只是执行onStop方法,执行stopActivityLocked

在stopActivityLocked方法里面我们可以看到r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);

最终就执行了onStop方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值