Instrumentation这个类,用来做测试。关于这个类,源码是这样介绍的:
/**
* 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.
*/
网上翻译意思大概是这样的:
用于实现应用程序代码的基类。当使用仪器进行运行时,该类将在任何应用程序代码之前为您实例化,
允许您监视系统与应用程序之间的所有交互。Instrumentation的实现类在AndroidManifest.xml通过
<instrumentation>进行声明。
也就是说系统通过这个方法,给我们监控app的代码执行提供了一个入口。
我们来看execStartActivity方法
/**
* Execute a startActivity call made by the application. The default
* implementation takes care of updating any active {@link ActivityMonitor}
* objects and dispatches this call to the system activity manager; you can
* override this to watch for the application to start an activity, and
* modify what happens when it does.
执行由应用程序调用的startActivity方法。默认的实现负责更新任何活动对象,
并将此调用发送给系统活动管理器;您可以覆盖此项以监视启动活动的应用程序,
以及修改当它发生时会发生什么。
*
* <p>This method returns an {@link ActivityResult} object, which you can
* use when intercepting application calls to avoid performing the start
* activity action but still return the result the application is
* expecting. To do this, override this method to catch the call to start
* activity so that it returns a new ActivityResult containing the results
* you would like the application to see, and don't call up to the super
* class. Note that an application is only expecting a result if
* <var>requestCode</var> is >= 0.
*
这个方法返回一个Activityresult对象.
您可以在拦截应用程序调用时使用它,以避免执行启动活动操作,但仍然返回应用程序期望的结果。
为此,重写此方法以捕捉start activity的调用,它返回一个新的Activityresult,
含有结果你想看到的应用程序,而不调用父类。注意,应用只在requestCode>0时需要一个结果.
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
*
这个方法如果找不到指定的Activity会抛出android.content.ActivityNotFoundException异常
* @param who The Context from which the activity is being started.
* @param contextThread The main thread of the Context from which the activity
* is being started.
* @param token Internal token identifying to the system who is starting
* the activity; may be null.
* @param target Which activity is performing the start (and thus receiving
* any result); may be null if this call is not being made
* from an activity.
* @param intent The actual Intent to start.
* @param requestCode Identifier for this request's result; less than zero
* if the caller is not expecting a result.
* @param options Addition options.
*
* @return To force the return of a particular result, return an
* ActivityResult object containing the desired data; otherwise
* return null. The default implementation always returns null.
*
* @throws android.content.ActivityNotFoundException
*
* @see Activity#startActivity(Intent)
* @see Activity#startActivityForResult(Intent, int)
* @see Activity#startActivityFromChild
*
* {@hide}
*/
该对象是在ActivityThread创建Activity时创建的,一个应用程序中只有一个Instrumentation对象,
每个Activity内部都有一个该对象的引用。Instrumentation可以理解为应用进程的管家,
ActivityThread要创建或者暂停某个Activity时,是通过这个"管家"进行的,
设置这个管家的好处是可以统计所有的"开销",开销的信息保存在"管家"那里。
其实正如其名称所示,Instrumentation就是为了"测量"、"统计",
因为管家掌握了所有的"开销",自然也就具有了统计的功能。
当然,Instrumentation类和ActivityThread的分工是有本质区别的,
后者就像是这个家里的主人,负责创建这个"家庭",并负责和外界打交道,比如接收AmS的通知等。
看一下execStartActivity的代码
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
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.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
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;
}
看这里
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
这里ActivityManagerNative.getDefault()返回了ActivityManagerProxy对象,ActivityManagerProxy通过Binder通信
最终会调用ActivityManagerService.java中的startActivity方法
转到ActivityManagerNative-getDefault
###参考资料