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