960 字
5 分钟
Start一个Activity
Context,Activity继承关系
首先,Activity是继承自ContextThemeWrapper,而ContextThemeWrapper继承自ContextWrapper,而ContextWrapper继承自Context,具体关系如下图:
Context 是一abstract类,基本没有实现,而真正的实现从名字就能看出来: ContextImpl
。ContextWrapper也是继承自Context,但是它同时持有一个Context对象,这个对象是通过attachBaseContext(base
/**
* @return the base context as set by the constructor or setBaseContext
*/
public Context getBaseContext() {
return mBase;
}
@Override
public AssetManager getAssets() {
return mBase.getAssets();
}
@Override
public Resources getResources() {
return mBase.getResources();
}
@Override
public PackageManager getPackageManager() {
return mBase.getPackageManager();
}
//... 省略号下面还有一万个这样的方法
也就是说,其实ContextWrapper虽然继承了Context,但是它只是一个代理类,实现都是通过ContextImpl。
启动默认Activity和通过Context.startActivity()在Android中是不一致的
LaunchActivity();
Activity.startActivity(…)
// 一号startActivity
public void startActivity(Intent intent) {
//调用 二号startActivity
this.startActivity(intent, null);
}
// 二号startActivity
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
// 三号startActivity
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
// 四号startActivity,这个是最终的Boss
public void startActivityForResult(Intent intent, int requestCode,Bundle options) {
// mParent是Activity类型,通过attach(...)方法初始化,而attact方法在哪里调用呢?
// TODO
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// 如果说没有Parent,则调用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) {
// 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;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
// 如果有mParent,则调用Parent.startActivityFromChild(...)
// Parent也是Activity,所以看看startActivityFromChild(...)这个方法
if (options != null) {
// 其中,child是this,当前类
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);
}
}
}
// 五号方法,有父Activity时候,startActivity会触发这个方法来启动Activity
// 跟上面那个方法差不多,只是多了一个child Activity
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
在调用startActivity后,最终都会触发下面这段代码,只不过child可能换成this:
// 其中的child,如果startActivity是由Activit发起,
// 则child为目标Activity,否则为自身
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
Instrumentation.execStartActivity(…)
接下来进入这个方法看一看
public ActivityResult execStartActivity(
Context who,//发起者,既谁调用的startActivity
IBinder contextThread, //TODO 认识ApplicationThread
IBinder token,
Activity target,// 要启动的目标Activity
Intent intent, // 用户传入的Intent
int requestCode,
Bundle options,
UserHandle user) {
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.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 看这里,最终跳转到ActivityManagerNative.getDefault()
int result = ActivityManagerNative.getDefault()
.startActivityAsUser(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options, user.getIdentifier());
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
然后我们在ActivityManagerNative找到该方法
public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options,
int userId) throws RemoteException {
...
// 最后的最后,发现它居然发了一个Binder消息,然后就不管了,那是谁接收和处理这个消息呢?
mRemote.transact(START_ACTIVITY_AS_USER_TRANSACTION, data, reply, 0);
...
}
ActivityManagerService
Dengdengdengdeng,当然是我们牛逼的ActivityManagerService来接收这个消息了,