从源码剖析Android中的Intent组件

2019-12-10 18:49:29于海丽

2、实例化Intent:

/**
* 创建一个Intent,直接指定Intent要激活的**组件类名**,而不用依赖**系统去解析**合适的类来处理intent
* @param packageContext 要执行这个intent的context对象
* @param cls intent要激活的组件类名
*/
public Intent(Context packageContext, Class cls) {
//创建一个组件并赋值给Intent的Component成员
  mComponent = new ComponentName(packageContext, cls);
}

3、启动Activity

startActivity(i) ->
startActivity(Intent intent, @Nullable Bundle options)->
startActivityForResult(intent, -1, options)


/** 
*startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options)
* 加载一个Activity并获取结果
* @param intent 要启动的intent.
* @param requestCode 如果大于0则会被返回,且只有返回值返回成功后才会显示视图
* @param options 其他信息.
*/
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) { //如果没有父Activity;Instrumentation是用来与程序指南清单AndroidManifest文件交互的。
  Instrumentation.ActivityResult ar =
  mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options); //执行startActivity命令
..... 
} else { //如果有父Activity
   if (options != null) {
     mParent.startActivityFromChild(this, intent, requestCode, options);
   } .....
}

4、执行startActivity命令核心代码:
启动Activity的任务交给了底层ActivityManagerNative来做。

intent.migrateExtraStreamToClipData(); //将intent里的bundle数据进行处理以便给底层处理
intent.prepareToLeaveProcess(); //准备离开应用程序进程,进入ActivityManagerService进程(意味着bundle的数据要在进程间传递)
int result = ActivityManagerNative.getDefault().startActivity(whoThread,   
who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options); //调用系统的activity manager服务来启动新的Activity。考虑如果是显式Intent,则直接找对对应的组件类(此处是Activity组件);如果是隐式Intent,为指定目标组件类名,则自动去Application->system搜索合适的组件来处理。
//todo:具体的系统级代码下次进行分析