本文主要是对activity的启动流程做一个简单分析
1、Activity.java
位于/frameworks/base/core/java/android/app/目录。有activity发起startActivity()请求,再调用到startActivityForResult()。
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
// Instrumentation是什么?mMainThread(ActivityThread)又是什么?
// ApplicationThread又是什么?
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
// ActivityThread.sendActivityResult()又做了什么?
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
ActivityThread.getApplicationThread()获取到的对象实际上是ActivityThread的一个内部类对象ApplicationThread,而ApplicationThread的父类ApplicationThreadNative又是什么呢?我们接着向下看。
2、Instrumentation.java
位于/frameworks/base/core/java/android/app/目录。其类的介绍如下:
/**
* Base class for implementing application instrumentation code. When running
* with instrumentation turned on, this class will be instantiated for you
* before any of the application code, allowing you to monitor all of the
* interaction the system has with the application. An Instrumentation
* implementation is described to the system through an AndroidManifest.xml's
* <instrumentation> tag.
*/
public class Instrumentation {
大体的意思就是说:这个类是应用测试框架的基本实现。如果测试框架打开,该类会最先初始化,并允许你监控到系统和应用的所有交互。如果你要使用自定义的测试框架,就必须在AndroidManifest.xml中使用instrumentation标签注明你的实现类。
注意:Instrumentation在我们写安卓的测试代码中是必须要用到的。我们在AndroidManifest.xml中声明的测试框架,实际就是继承与这个Instrumentation。activity的很多对外操作,都将通过该类传递出去,外部信息也将通过该类传递到activity。猜想:如果需要实现一些特殊的功能,比如说权限监控,应该可以通过重写该类实现。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 实际上是ActivityThread的一个内部类对象ApplicationThread
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
// 在同一进程内寻找匹配的activity
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.setAllowFds(false);
intent.migrateExtraStreamToClipData();
// 在不同进程内寻找匹配的activity,借助ActivityManagerNative实现跨进程通讯
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
// 检查返回值,必要时抛出ActivityNotFoundException异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
ApplicationThread继承与ApplicationThreadNative,而ApplicationThreadNative则实现了IApplicationThread的接口。好吧,这个是不是和native binder相关类中介绍的native binder的继承层次类似?确实是这样的!IApplicationThread定义了一系列的binder接口,而ApplicationThreadNative是IApplicationThread的Bn端框架实现,ApplicationThreadNative中定义的另一个ApplicationThreadProxy类,则是IApplicationThread的Bp端框架实现。
ActivityMonitor是Instrumentation的内部类,主要是记录了Instrumentation启动的activity信息,包括IntentFilter、class、result等信息。
Instrumentation.execStartActivity()方法,现在其内部的ActivityMonitor队列中查找匹配的activity。如果没有找到,则进入到ActivityManagerNative.startActivity()中,并调用checkStartActivityResult()检查返回结果,判断是否出了异常。
IApplicationThread的接口定义如下。大家有没有觉得这些接口和activity的生命周期类似?实际上,这些接口是ActivityManagerService用来直接控制Activity的。
public interface IApplicationThread extends IInterface {
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException;
void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, int configChanges,
boolean notResumed, Configuration config) throws RemoteException;
void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
void scheduleDestroyActivity(IBinder token, boolean finished,
int configChanges) throws RemoteException;
// 。。。。省略
4、ActivityManagerNative.java
位于/frameworks/base/core/java/android/app/目录下,与其对应的是IActivityManager.java接口定义。它们之间的关系和前边介绍的ApplicationThreadNative.java、IApplicationThread.java的关系一样,就不再分析。IActivityManager定义了接口;ActivityManagerNative继承与Binder,实现了IActivityManager接口,是IActivityManager的Bn端实现;而ActivityManagerNative的内部类ActivityManagerProxy则是IActivityManager接口的Bp端实现。以下是它的一些binder接口:
public interface IActivityManager extends IInterface {
public int startActivity(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
public int startActivityAsUser(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
public WaitResult startActivityAndWait(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, String profileFile,
ParcelFileDescriptor profileFd, Bundle options, int userId)
// 。。。。省略
怎么样?这些接口和我们在Context中定义的一些接口是不是很像?
看看ActivityManagerNative的几个关键方法:
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
// 从ServiceManager处获取activity manager的binder对象
IBinder b = ServiceManager.getService("activity");
// 将binder对象转换为接口对象
IActivityManager am = asInterface(b);
return am;
}
};
5、ActivityManagerService.java
位于/frameworks/base/services/java/com/android/server/am目录。继承与ActivityManagerNative,也就是说它是IActivityManager的Bn端实现。它管理系统内所有的activity(通过ActivityStack管理)、service、provider和receiver。应用层调用的startActivity()方法最终会到达ActivityManagerService中。
public final int startActivity(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
public final int startActivityAsUser(IApplicationThread caller,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivity", null);
return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
null, null, options, userId);
}
可以看到startActivity()传递到了mMainStack(ActivityStack对象)。
6、ActivityStack.java
位于/frameworks/base/services/java/com/android/server/am目录。ActivityStack主要是用来存储和管理所有的Activity的。Activity在ActivityStack中的表现形式是ActivityRecord。ActivityStack管理所有activity的堆栈结构,BnActivityManagerService的命令都会传到ActivityStack中,最终传递到相应的activity进程中。而相应的activity执行命令,状态发生变化,并将状态上报到ActivityManagerService,并最终保存在ActivityStack中的某一个ActivityRecorder。
final int startActivityMayWait(IApplicationThread caller, int callingUid,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, String profileFile,
ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Bundle options, int userId) {
// 。。。。省略,检查intent的合法性
// Collect information about the target of the Intent.
// 解析activity信息,包名、类名、theme、label、lunch mode等等
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
profileFile, profileFd, userId);
synchronized (mService) {
if (mMainStack && aInfo != null &&
(aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
// This may be a heavy-weight process! Check to see if we already
// have another, different heavy-weight process running.
if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
if (mService.mHeavyWeightProcess != null &&
(mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
!mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
// 。。。。省略,如果同一包名的进程已经启动,则获取ProcessRecord信息,并使用ProcessRecord中的uid和pid信息,修正caller uid和pid信息。
}
}
}
// 启动activity
int res = startActivityLocked(caller, intent, resolvedType,
aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
startFlags, options, componentSpecified, null);
if (mConfigWillChange && mMainStack) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
// 更新configuration
mService.updateConfigurationLocked(config, null, false, false);
}
Binder.restoreCallingIdentity(origId);
if (outResult != null) { // 回数据给caller
outResult.result = res;
if (res == ActivityManager.START_SUCCESS) { // 启动成功
mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait(); // 等待新的activity启动
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
// 后台进程切换到前台
} else if (res == ActivityManager.START_TASK_TO_FRONT) {
ActivityRecord r = this.topRunningActivityLocked(null);
if (r.nowVisible) {
outResult.timeout = false;
outResult.who = new ComponentName(r.info.packageName, r.info.name);
outResult.totalTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
mWaitingActivityVisible.add(outResult);
do {
try {
mService.wait(); // 等待新的activity启动
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
}
}
}
return res;
}
}
ActivityStack会先检查intent的合法性,然后解析activity的信息。如果activity对应的进程已经启动过,则修正启动caller的信息。然后调用了startActivityLocked(),最后如果需要返回数据,则wait等待新的activity的启动结果。
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, int startFlags, Bundle options,
boolean componentSpecified, ActivityRecord[] outActivity) {
int err = ActivityManager.START_SUCCESS;
// 。。。。省略,获取caller信息
int launchFlags = intent.getFlags();
if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
&& sourceRecord != null) {
// Transfer the result target from the source activity to the new
// one being started, including any failures.
if (requestCode >= 0) {
ActivityOptions.abort(options);
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
// 。。。。省略,修正result信息
}
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// We couldn't find a class that can handle the given Intent.
// That's the end of that!
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
// We couldn't find the specific class specified in the Intent.
// Also the end of the line.
err = ActivityManager.START_CLASS_NOT_FOUND;
}
if (err != ActivityManager.START_SUCCESS) {
if (resultRecord != null) {
// 将启动错误返回给caller,最终通过ApplicationThread的scheduleSendResult()通知到activity
sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
mDismissKeyguardOnNextActivity = false;
ActivityOptions.abort(options);
return err;
}
// 权限检查
final int startAnyPerm = mService.checkPermission(
START_ANY_ACTIVITY, callingPid, callingUid);
final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);
if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
if (resultRecord != null) {
// 返回错误
sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
throw new SecurityException(msg);
}
ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified);
if (outActivity != null) {
outActivity[0] = r;
}
err = startActivityUncheckedLocked(r, sourceRecord,
startFlags, true, options);
return err;
}
7、总结
Instrumentation作为中间者(Activity的成员变量),用来监控activity和系统的交互。
Instrumentation通过BpActivityManager(ActivityManagerNative)发送命令到ApplicationManagerService(发送命令时,附带了binder对象),而ApplicationManagerService则通过BpApplicationThread(ApplicationThreadNative)控制到ActivityThread,再控制到Activity。