为什么要学习源码?
这是源码分析系列的第三篇博客了,这里我说明一下为什么要进行Activity启动流程的源码分析。
学习源码有助于我们学习一些黑科技,比如学习插件化的从时候我们需要学习Hook机制,但是学习Hook机制的时候我们需要掌握Activity的启动流程、消息机制等等机制。
Activity启动流程分析
我们平常在Activity中调用startActivity(intent)来启动一个Activity的时候,通过调用链的分析,最终会调用Activity的startActivityForResult方法:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//调用Instrumentation类的execStartActivity方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
//如果需要有结果返回的话,还需要去发送消息
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
这个方法实际会调用Instrumentation类的execStartActivity方法,Instrumentation类与Activity的初始化有关。Instrumentation类的execStartActivity方法如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//IApplicationThread是一个AIDL接口,实现类是ActivityThread里的内部类ApplicationThread通过他可以进行进程间通信,通过ApplicationThread可以识别出一个进程。
IApplicationThread whoThread = (IApplicationThread) contextThread;
//...省略一些代码
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//ActivityManagerNative是一个AIDL接口的二分之一:Stub(存根)
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManagerNative是一个AIDL接口的二分之一:Stub,与AMS进行通信的。ActivityManagerNative里面还有一个内部类ActivityManagerProxy。如下图所示:
因此到这里已经开始了进程间通信了,通过通知AMS去进行后续的处理。
之前已经分析过了,通过ActivityManagerNative.getDefault()得到的实质上是ActivityManagerNative与AMS进行通信的一个AIDL接口的引用:
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
而实现这个接口的正是ActivityManagerNative的一个内部类ActivityManagerProxy:
class ActivityManagerProxy implements IActivityManager{
}
那么这个ActivityManagerProxy就是向AMS的IBinder写数据的,比如说启动Activity的时候就需要进行进程间通信了,我们把数据都放到可序列化的Parcel对象里面,写到IBinder驱动里面去。
下面是ActivityManagerProxy中startActivity的实现:
//caller代表着应用,调用者,比如说通过桌面启动Activity的话,caller就是代表着Launcher的描述。
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
//这里省略一些写数据的代码
//调用transact方法向IBinder驱动写数据
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
//读取跨进程通信的时候是否有异常
reply.readException();
int result = reply.readInt();
//回收数据,防止内存泄漏
reply.recycle();
data.recycle();
return result;
}
数据写到Binder驱动里面去之后就会回调ActivityManagerNative(也就是Stub)的onTransact方法,这个方法比较长,还包括很多其他的case,这里只抽取了一部分核心代码。
根据我们transact的code(START_ACTIVITY_TRANSACTION),可以过滤出下面的代码:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
//将IBinder接口转换为AIDL的引用
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
//省略一些获取参数的代码
//ActivityManagerNative的真正实现类是AMS,因此这里是调用AMS的startActivity方法
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
}
ActivityManagerNative的真正实现类是ActivityManagerService(AMS),AMS与四大组件的创建、传播、生命周期的管理里面起到了重要的作用。
这里是调用了AMS的startActivity方法:
@Override
public final int startActivity(...省略一些参数) {
return startActivityAsUser(...省略一些参数);
}
而AMS的startActivity里面又会调用startActivityAsUser方法:
@Override
public final int startActivityAsUser(...省略一些参数) {
//拿到启动的信息
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
//这里又会调用ActivityStarter的startActivityMayWait方法:
return mActivityStarter.startActivityMayWait(...省略一些参数);
}
ActivityStackSupervisor是APP的栈的管理类,管理四大组件的栈的问题。而ActivityStarter就是每一个被管理的任务栈。分Task任务来管理,一个任务里面可能多个栈,别说当前正在使用、已停止的栈、历史栈。
ActivityStackSupervisor里面记录了一大堆Activity的记录:
final ArrayList mStoppingActivities = new ArrayList<>();
final ArrayList mFinishingActivities = new ArrayList<>();
这里又会调用ActivityStarter的startActivityMayWait方法:
final int startActivityMayWait(...省略一些参数) {
mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
boolean componentSpecified = intent.getComponent() != null;
//封装出一个Intent来
intent = new Intent(intent);
//这里经历了一个PMS(PackageManagerService)对Intent的验证过程,验证这个Activity在清单文件里面是否有定义,这一步很重要,将来我们学习Hook机制免清单注册启动Activity的时候这是比较关键的
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
//省略一些代码
//把目标的Activity的信息提取出来
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
//省略一些代码
synchronized (mService) {
//通过获取Binder获取我们启动这个Activity的进程id,Uid
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
//省略一些代码
final ActivityRecord[] outRecord = new ActivityRecord[1];
//继续调用startActivityLocked方法:
int res = startActivityLocked(...省略一些参数);
//省略一些代码
}
}
上面的函数里面比较重要的就是下面这一行代码:
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
这里调用了ActivityStackSupervisor的resolveIntent,通过调用链分析得到实际上是调用了下面这个方法:
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
try {
return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY | flags
| ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
return null;
}
我们平时启动Activity的时候,如果要检测有没有对应Activity的话,就需要resolveIntent方法。
这里PMS会去找清单文件,是否有注册的Activity,尤其是隐式意图启动Activity的时候。
下面我们看AppGlobals里面getPackageManager方法的定义,其返回的是IPackageManager,这是一个AIDL接口。
public static IPackageManager getPackageManager() {
return ActivityThread.getPackageManager();
}
下面看看ActivityThread里面的getPackageManager方法,实际上就是一个“叫服务”的过程,实际就是拿到IBinder引用,然后通过asInterface方法转换为与PMS通信的AIDL接口的引用:
public static IPackageManager getPackageManager() {
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
整个过程就是拿到PackageManager的AIDL引用,然后调用他的resolveIntent方法,而这个IPackageManager的实现类就是谁呢?不是PackageManager,因为他只是一个单独的类:
public abstract class PackageManager {
}
IPackageManager的真正实现类是PackageManagerService(PMS),这是一个系统服务:
public class PackageManagerService extends IPackageManager.Stub {
}
PackageManagerService里面的resolveIntent方法实现如下:
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
try {
//省略一些代码
//查找是否存在这个Intent代表的Activity,返回的结果可能有多个
final List query = queryIntentActivitiesInternal(intent, resolvedType,
flags, userId);
//选择最好(最符合条件)的一个Activity
final ResolveInfo bestChoice =
chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
PackageManagerService在Android系统启动的时候就会启动,并且会扫描所有的已经安装的应用的清单文件,然后保存到内存当中。这里调用了queryIntentActivitiesInternal方法去找符合Intent过滤条件的Activity列表。
该方法的实现如下:
private @NonNull List queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
//省略一些代码
//拿到Intent的Component
ComponentName comp = intent.getComponent();
//省略一些代码
if (comp != null) {
final List list = new ArrayList(1);
//通过组件名、flags、userId获取Activity信息
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
//如果能够找到对应的Activity,就会添加到list里面去,最后返回
list.add(ri);
}
return list;
}
//后面省略一些Intent先后排序的代码
return result;
}
在PackageManagerService里面的resolveIntent方法最后,还会考虑到Intent的优先级问题,也就是调用chooseBestActivity,选择最好的Activity:
- 如果查询结果只有一个的话,那么直接返回第0个;否则需要处理优先级的问题。
- 否则如果我们只启动一个Activity的话,就要根据priority优先级来判断了。(所以清单文件里面有优先级的配置)。
下面我们稍微研究一些关于PMS的chooseBestActivity方法:
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List query, int userId) {
if (query != null) {
final int N = query.size();
//如果查询结果只有一个的话,那么直接返回第0个;否则需要处理优先级的问题
if (N == 1) {
return query.get(0);
} else if (N > 1) {
ResolveInfo r0 = query.get(0);
ResolveInfo r1 = query.get(1);
//如果我们只启动一个Activity的话,就要根据priority优先级来判断了。(所以清单文件里面有优先级的配置)
if (r0.priority != r1.priority
|| r0.preferredOrder != r1.preferredOrder
|| r0.isDefault != r1.isDefault) {
return query.get(0);
}
//省略一些代码
}
}
return null;
}
也就是说这里系统通过PMS去做了一个验证,判断清单文件里面是否有这个Activity,并且返回最好的一个。
PMS主要用来管理包的信息,而包的信息保存在清单文件。例如他回去/data/data目录去扫描。例如在PMS构造的时候你会发现这些代码:
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
synchronized (mPackages) {
//需要扫描的目录
File dataDir = Environment.getDataDirectory();
//data/data/app:第三方APP的安装目录
mAppInstallDir = new File(dataDir, "app");
mAppLib32InstallDir = new File(dataDir, "app-lib");
mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
//data/data/app-private:系统APP的安装目录
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
if (!mOnlyCore) {
//调用scanDirLI去扫描
scanDirLI(mEphemeralInstallDir, mDefParseFlags
| PackageParser.PARSE_IS_EPHEMERAL,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
}
}
}
PMS的scanDirLI方法如下:
private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
for (File file : files) {
//扫描,判断是不是APK文件
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
continue;
}
try {
//然后去解析APK的清单文件,把四大组件的信息、权限等解析出来
scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
}
}
}
一开机的时候,SystemServer启动之后就会启动PMS,就会调用PMS的main方法,把自己注册到ServiceManager里面去:
ServiceManager就是我们的服务总台,保存所有服务的“联系方式”。
public static PackageManagerService main(...省略一些参数) {
PackageManagerServiceCompilerMapping.checkProperties();
//new一个PMS,PMS在构造方法的时候就会去扫描清单文件
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
//把自己注册到ServiceManager里面去
ServiceManager.addService("package", m);
return m;
}
我们回到ActivityStarter的startActivityMayWait方法,继续走会发现调用了startActivityLocked方法:
//继续调用startActivityLocked方法:
int res = startActivityLocked(...省略一些参数);
这是ActivityStarter的startActivityLocked方法:
final int startActivityLocked(...省略一些参数) {
//初始化了一个错误标志,常见的错误有很多,比如:找不到Activity,Activity没有在清单文件中注册等等
int err = ActivityManager.START_SUCCESS;
//获取调用者的一些信息
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
err = ActivityManager.START_PERMISSION_DENIED;
}
}
//省略一些代码
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
//错误:找不到Activity的意图
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
//错误:找不到Activity的Class类,比如说清单文件里面的类名写错了
err = ActivityManager.START_CLASS_NOT_FOUND;
}
//省略一些代码
//省略验证权限相关的代码,因为一个Activity的启动可能需要一些权限,尤其是自定义权限的时候
if (Build.PERMISSIONS_REVIEW_REQUIRED && aInfo != null) {
if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
}
}
//如果没有错误信息的话,就会创建一个ActivityRecord,记录着Activity的各种信息,例如返回结果的时候需要跳到哪个Activity的信息,Activity所在的进程(例如启动一个没有进程的Activity的时候,如果发现ActivityRecord里面的进程没有被启动的时候,就需要去孵化一个进程,这里在后面会有所分析)
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
options, sourceRecord);
//省略一些代码
try {
mService.mWindowManager.deferSurfaceLayout();
//调用startActivityUnchecked,无需检查,真正去启动
err = startActivityUnchecked(...省略一些参数);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
return err;
}
调用startActivityUnchecked,无需检查其他东西去启动Activity:
这个方法处理了Activity的启动模式,比如是否需要新建一个任务栈,栈里面是否需要复用已经存在的Activity实例等等。而且启动模式还要配合flag,比如说NEW_TASK等。
并且在清单文件里面的启动模式的配置要优先于flags。
private int startActivityUnchecked(...省略一些参数) {
//省略一些代码
if (mReusedActivity != null) {
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| mLaunchSingleInstance || mLaunchSingleTask) {
//查询顶端的Activity
final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked(
mStartActivity, mLaunchFlags);
if (top != null) {
if (top.frontOfTask) {
top.task.setIntent(mStartActivity);
}
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
}
}
//省略一些代码
}
if (mStartActivity.packageName == null) {
if (mStartActivity.resultTo != null && mStartActivity.resultTo.task.stack != null) {
mStartActivity.resultTo.task.stack.sendActivityResultLocked(
-1, mStartActivity.resultTo, mStartActivity.resultWho,
mStartActivity.requestCode, RESULT_CANCELED, null);
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
//省略一些代码
//调用目标的Activity栈的startActivityLocked方法
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
//省略一些代码
}
Activity任务栈(Task)
任务栈里面存放着ActivityRecord,是一种后进先出的数据结构。
比如Launcher去启动Activity的时候,就需要新建一个任务栈。调用系统的应用的时候,比如相机,如果不指定NEW_TASK,就会在自己的APP的任务栈里面启动。
比较特殊的就是单例模式,就是会新建一个任务栈。
栈也有顺序的,我们看到的是正在显示的栈,退出这个栈以后,就会显示下一个栈。
在上面的方法的最后会调用目标的Activity栈的startActivityLocked方法:
//调用目标的Activity栈的startActivityLocked方法
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
- ActivityStackSupervisor:APP的栈的管理类(管理的时候也是用栈的模型),比如哪个任务栈需要显示,Activity需要选择哪个栈去进栈,并且检查Intent的flags。
- ActivityStack:就是一个个被ActivityStackSupervisor管理的栈,管理者Activity。
下面我们分析ActivityStack的startActivityLocked:
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
ActivityOptions options) {
//找到需要启动的Activity的任务栈,因为每一个Activity一定会分配一个任务栈
TaskRecord rTask = r.task;
//那大任务栈的ID
final int taskId = rTask.taskId;
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
//如果不是后置任务(某些Activity进栈之后还要处理一些操作),那就把这个任务栈加到最顶端,也就是成为有焦点的栈
//告诉WindowManager,把Task移到顶部,因为窗口的显示是由WindowManager来控制的。并且显示这个任务栈里面最顶部的Activity。
insertTaskAtTop(rTask, r);
mWindowManager.moveTaskToTop(taskId);
}
TaskRecord task = null;
if (!newTask) {
//如果不需要启动一个新的任务栈的话,直接重复利用当前的Task
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == r.task) {
if (!startIt) {
//如果不需要启动一个新的任务栈,直接把Activity添加到当前最顶部的TASK,并且放到顶部
task.addActivityToTop(r);
//添加到回退栈
r.putInHistory();
//省略一些代码
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
//需要新建一个任务栈的话,就新建一个,然后添加Activity,通知WM,具体代码就不看了。
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
mStackSupervisor.mUserLeaving = false;
}
task = r.task;
task.addActivityToTop(r);
task.setFrontOfTask();
//...省略一些代码
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
接着调用ActivityStackSupervisor的resumeTopActivitiesLocked,下面继续分析:
boolean resumeTopActivitiesLocked() {
return resumeTopActivitiesLocked(null, null, null);
}
根据调用关系链,会调用下面这个方法:
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
//省略一些代码
if (isFrontStack(targetStack)) {
//调用ActivityStack的resumeTopActivityLocked方法查找需要暂停的Activity
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
//省略一些代码
}
ActivityStack的resumeTopActivityLocked如下:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
//省略一些代码
try {
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}
然后调用resumeTopActivityInnerLocked:
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
//省略一些代码
//找到第一个没有被销毁的Activity,根据ActivityStackSupervisor的成员变量所保存的数组来查找
//所找到的Activity将来准备要进入暂停状态
//我们的APP所有Activity任务栈统一通过进程通信交给ActivityStackSupervisor管理所有任务栈。
//因为ActivityStackSupervisor知道整个系统的哪个进程死了,需要显示哪个任务栈
ActivityRecord next = topRunningActivityLocked(null);
//省略一些代码
//需要把当前准备暂停的Activity,从一些状态数组里面移除
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
//调用startPausingLocked暂停最顶部的Activity,通过这样做的话,它将来就能够复活resume
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
//省略一些代码
ActivityStack lastStack = mStackSupervisor.getLastStack();
//一个Activity要启动的话,需要先判断app以及thread还存不存在,如不存在就需要重新创建一个进程。
//比如说从launcher启动Activity
if (next.app != null && next.app.thread != null) {
//无需创建进程
} else {
//需要启动的的Activity还没有启动对应的进程,需要去启动进程
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
//省略一些代码
//重新启动进程
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
startPausingLocked:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
//找到上一个需要暂停的Activity
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (!resuming) {
mStackSupervisor.resumeTopActivitiesLocked();
}
return false;
}
//先判断之前的Activity是否存在,如果存在,需要进行进程间通信,通知那个app去停止Activity
//之所以每一个Activity都需要用一个ActivityRecord去记录,就是因为需要记录每一个Activity所在进程等等信息,方便系统去管理
if (prev.app != null && prev.app.thread != null) {
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
//如果存在,需要进行进程间通信,通知那个app去停止Activity
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
}
//省略一些代码
}
schedulePauseActivity方法会发起进程间通信,通知即将要停止的Activity所在的进程,去暂停这个Activity。最终会在那个进程的ActivityThread里面回调schedulePauseActivity方法:
实质上就是发送消息给Handler,然后调用,去停止Activity。
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
//省略一些代码
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
Handler里面的case如下:
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
handlePauseActivity:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
//真正去执行暂停Activity
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// Tell the activity manager we have paused.也就是说,先停止,然后回馈给AMS的activityPaused方法
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
performPauseActivity:
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
然后又会调用performPauseActivity:
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
//省略一些代码
try {
//省略一些代码
//真正去停止Activity
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
}
}
然后:
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
最后回调Activity的onPause方法
final void performPause() {
//省略一些代码
onPause();
//省略一些代码
}
在handlePauseActivity的最后还要:
// Tell the activity manager we have paused.也就是说,先停止,然后回馈给AMS的activityPaused方法
// 这就解释了为什么新启动的Activity启动之前,旧的先onPause
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
//AMS去启动栈顶部Activity
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
ActivityStackSupervisor、ActivityStack只是管理了Activity的栈,栈放什么,而真真正正去处理四大组件启动的还是AMS服务。之前的一系列操作只是进行了一些栈的管理操作,然后通知APP进程暂停,然后APP进程再去通知AMS去启动栈顶部Activity。
//Activity已经暂停了
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
//然后调用completePauseLocked,表示上一个Activity已经停止完成了,然后resume要启动的Activity
completePauseLocked(true);
}
}
}
然后调用completePauseLocked,表示上一个Activity已经停止完成了,然后resume要启动的Activity:
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
//省略一些代码
if (resumeNext) {
//拿到顶部任务栈
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
}
}
//省略一些代码
}
然后调用:
boolean resumeTopActivitiesLocked() {
return resumeTopActivitiesLocked(null, null, null);
}
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
//省略一些代码
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
//省略一些代码
}
又会回来调用ActivityStack的resumeTopActivityLocked,里面继续调用resumeTopActivityInnerLocked:
if (next.app != null && next.app.thread != null) {
//不需要启动进程
} else {
//需要启动进程
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
}
//省略一些代码
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
先判断app的进程有没有启动,例如连续启动。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//省略一些代码
if (app != null && app.thread != null) {
//不需要启动进程
}
//启动进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
调用AMS的方法来启动进程:
//看到hosting,证明Java准备跟底层的C/C++通信了
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(...省略一些参数);
}
final ProcessRecord startProcessLocked(...省略一些参数) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
//省略一些代码
//创建app对象,但是这时候进程还没启动
//省略一些代码
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
}
//启动进程
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
}
启动进程:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
//省略一些代码
try {
if (!app.isolated) {
//省略一些代码
//获取PID、UID
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
checkTime(startTime, "startProcess: building args");
if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopComponent != null
//获取包名
&& app.processName.equals(mTopComponent.getPackageName())) {
uid = 0;
}
}
int debugFlags = 0;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
//开始配置Zygote进程
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
// Also turn on CheckJNI for debuggable apps. It's quite
// awkward to turn on otherwise.
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
//省略一些代码
//android.app.ActivityThread是Java层的入口类
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
//开始启动进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
//开始拼装启动的脚本,最后写到C/C++里面
StringBuilder buf = mStringBuilder;
buf.setLength(0);
buf.append("Start proc ");
buf.append(startResult.pid);
buf.append(':');
buf.append(app.processName);
buf.append('/');
//省略一些脚本的拼装
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
//把这些信息拼装成一个消息,然后通过Handler来处理,最后是跟底层通信,通过C/C++的方式去启动进程
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
} catch (RuntimeException e) {
}
}
最后ActivityThread会启动,启动ActivityThread的main方法:
public static void main(String[] args) {
//省略一些代码
Environment.initForCurrentUser();
Process.setArgV0("");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
//把当前进程attach到系统中
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
如下:
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//调用IActivityManager,通过进程间通信,绑定Application。IActivityManager的实现类是AMS
//查看AMS的实现之后,又会调用attachApplicationLocked,然后又会调用ActivityStackSupervisor的attachApplicationLocked
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
}
//省略一些代码
}
AMS的attachApplicationLocked方法有一句核心代码如下,然后又会调用ActivityStackSupervisor的attachApplicationLocked:
//如果进程已经启动了,而且在栈顶部有一个属于这个进程的Activity需要启动
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
进程被创建,不一定需要Activity的启动。Activity跟进程还没有关联,因此realStartActivityLocked:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
for (...省略) {
ArrayList stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (...省略) {
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//继续调用realStartActivityLocked
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
}
}
}
}
}
}
realStartActivityLocked里面有这样一句:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
通过进程间通信,回到APP的ActivityThread,发送消息给H,然后启动:
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
然后:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//省略一些代码
//先初始化窗口
WindowManagerGlobal.initialize();
//然后performLaunchActivity
Activity a = performLaunchActivity(r, customIntent);
//省略一些代码
}
performLaunchActivity:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
//通过反射的方式去创建Activity
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//省略一些代码
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
//设置主题
activity.setTheme(theme);
}
activity.mCalled = false;
//回调OnCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
//回调onStart、onResum等
activity.performStart();
r.stopped = false;
}
}
} catch (SuperNotCalledException e) {
} catch (Exception e) {
}
return activity;
}
关于newActivity:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
几个有关的核心类
- ActivityManagerService(本地Stub是ActivityManagerNative):系统进程里面的一个服务,管理四大组件的生命周期等等。
- ActivityThread:Android应用程序的Java层入口函数。
- PackageManagerService:清单的扫描、注册。
- ActivityStackSupervisor:管理所有任务栈,是通过栈的模型去管理的,是否需要新建任务栈?等等。
- ActivityStack:任务栈,管理任务栈里面的Activity。
- WindowManager:只管理当前最顶部的栈的Activity的UI的渲染。
Activity的启动总结如下:
这里先对这个图进行一些必要的说明:
- 这是MyActivity的启动流程,流程是从左边开始,逆时针旋转。主要展示了Application怎么调到Android System Service,Android System Service如何反过来调Application。
- Instrumentation是Activity的一个成员,这里用聚合表示。Instrumentation用于记录Activity的一切操作。
- Application以及H都是ActivityThread的内部类
- ActivityManagerService,简称AMS,是Android系统服务中的一个核心模块,其他的还有WindowsManagerService(WMS)、PackageManagerService(PMS)、NotificationManagerService(NMS)等等。AMS主要的功能是管理应用进程以及应用进程中的组件、内存管理。
- 从上面的图可以看出Android系统的几个明显的层次关系。
思想
- 大量采用了C/S架构,交给远程进程统一管理,这样才能够实现多进程,多窗口,有条不紊。
- 模块化的思想,不同的模块管理不同的东西。多建立package,分模块,比如说网络访问专门一个包。
- 分层次思想,不能一个类所有事情都管理了。
如果觉得我的文字对你有所帮助的话,欢迎关注我的公众号:
我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)。