关于此课题我将分为上,中,下三部分解析
应用进程内
一 如何使用Intent做Activity的跳转
Intnet intent = new Intent(MainActivity.this,TestActivity.class);
startActivity(intent);
我们通常会这样写,就能跳转到TestActivity中,但是你知道这简简单单的两行代码在我们庞大的安卓系统中经历了怎样的加工处理吗?接下来我带大家深入到系统内了解整个的启动过程
这里调用了startActivity的函数,这个函数被声明在了Context类中,然后我们的Activity类有重写版本,所以会执行Activity类下的版本,我们跟进。大家准备好了吗。我要发车了!
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
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 {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
上面有四个函数,基本上都是简单的判断和一些代码的封装,在最后一个函数中,执行了mInstrumentation对象下的execStartActivity函数,这个函数会做一些脱离应用进程的操作,准备通过IBinder机制将请求发送到Ams中。简单说一下传入参数
1.this指的就是我们的MainActivity对象,标明谁是发起者
2.getApplicationThread 获取的是应用标示,因为Android系统中每一个应用都是一个客户,而Ams更像是柜台服务人员
3.mToken是系统的一个内部标示,是ActivityRecord类下的一个静态内部类,里边用弱引用存了一个ActivityRecord对象,会在startActivityForResult函数中应用,标明应该调用谁的onActivityResult函数,后面会有讲到
4.同第一个参数,标明了发起者是谁
5.intent就略过吧,很常用了
6.requestCode这个值也很常用,所以也不做详细介绍了,默认-1
7.options是我们跳转页面需要携带的参数,当然没有参数自然也会是null了
二 接下来我们了解完参数后看一下内部实现吧
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);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(wh