首先我们最常见的activity都是最终继承自Context,很多的实现并不是完全在acitivty.java中实现的。
比如我们常见的启动一个activity-〉startActivity(),有两种
1.我们常见的在activity中做的调转是调用activity中的startActivity();
2.mContext.startActivity则一般是调用的是ContextImpl的startActivity() (而ContextImpl的创建是在ActivityThread中完成的)。该mContext是指从系统进程中创建的Context对象
它们共同都是调用Instrumentation的execStartActivity()
如:
ActivityThread->performLaunchActivity()中有一端对ContextImpl进行了创建以及传递了引用,
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {............
if (activity != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}.............
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
其它的如ContextWrapper只是对Context的一重包装,一个包装过的类,它里面必须要包含一个真正的Context引用;ContextWrapper中提供了attachBaseContext()来指定真正的context对象,调用ContextWrapper的方法都会被转向其所包含的真正的Context对象。
ContextImpl:
@Override
public void startActivity(Intent intent) {
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity)null, intent, -1);
}
主要是通过getInstrumentation().execStartActivity这个方法里去调用的,那么我们现在来看execStartActivity()这个方法。
它在叫Instrumentation.java这个类中:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
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.setAllowFds(false);
//从这里可以看出是调用了本地方法,进行对activity进行启动的
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false, null, null, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
从上面的代码可以看出,是由本地方法对activity进行了启动。