1、使用的是Android 7.1.2的源代码:
https://pan.baidu.com/s/1XcVD68cC_2wKtm8jJkdNQA
przv
2、感谢IT先森的系列博客:
Android应用进程创建流程大揭秘
Android四大组件之bindService源码实现详解
Android四大组件之Activity启动流程源码实现详解概要
Activity启动流程(一)发起端进程请求启动目标Activity
Activity启动流程(二)system_server进程处理启动Activity请求
Activity启动流程(三)-Activity Task调度算法复盘分析
Activity启动流程(四)-Pause前台显示Activity,Resume目标Activity
Activity启动流程(五)请求并创建目标Activity进程
Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application
Activity启动流程(七)初始化目标Activity并执行相关生命周期流程
问题1:在Activity的启动过程中,PMS在显式隐式调用的用处,即显式隐式是如何拿到Activity对象的?
问题2:Component属性
- 通过PMS解析 Intent 获取到合适的ResolveInfo(启动包含了ActivityInfo信息):
PMS.queryIntentActivitiesInternal中可以看出通过PMS解析 Intent 获取到合适的ResolveInfo(启动包含了ActivityInfo信息):
① 查看当前Intent是否是显式Intent,是则取出其中的class对象和AndroidManifest的进行匹配,匹配成功返回
② 如果没有指定包名则全系统的查找匹配intent
③ 如果指定包名,则从当前的包名寻找匹配规则相符合的intent的Activity
- 显式Intent的话,直接可以根据comp来解析到Intent的ActivityInfo信息;隐式Intent的话,需要自己匹配到ActivityInfo信息,然后给Intent设置comp
1、ComponentName
1.1 简介
ComponentName:和Intent同位于android.content包下。在Android应用程序中如果要详细描述一个组件需要知道该组件所在的应用包名和该组件在应用程序中的完整路径名。
其中 应用包名 是在AndroidManifest.xml中manifest根节点下的package=“X.X.X”,组件的完整路径名 比如Activity为activity节点中name属性的值。
1.2 使用方式
ComponentName的使用方式:
ComponentName(String pkg, String cls):创建pkg所在包下的cls类所对应的组件
ComponentName(Context pkg, String cls):创建pkg所对应的包下的cls类所对应的组件
ComponentName(Context pkg, Class<?> cls):创建pkg所对应的包下的cls类所对应的组件
ComponentName cn = new ComponentName("com.example.activitylifecycle", "com.example.activitylifecycle.SecondActivity"); //1
ComponentName cn = new ComponentName(MainActivity.this, "com.example.activitylifecycle.SecondActivity"); //2
ComponentName cn = new ComponentName(MainActivity.this, SecondActivity.class); //3
startActivity(new Intent().setComponent(cn));
2、显式Intent启动Activity(设置Component)
2.1 简介
显式:直接指定需要打开的Activity对应的类
2.2 使用方式
方式1:
Intent intent = new Intent(this, SecondActivity.class)
startActivity(intent);
方式2:
ComponentName componentName = new ComponentName(this, SecondActivity.class);
// 或者ComponentName componentName = new ComponentName(this, "com.example.app016.SecondActivity");
// 或者ComponentName componentName = new ComponentName(this.getPackageName(), "com.example.app016.SecondActivity");
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
方式3:
Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);
// 或者intent.setClassName(this, "com.example.app016.SecondActivity");
// 或者intent.setClassName(this.getPackageName(), "com.example.app016.SecondActivity");
startActivity(intent);
2.3 显式Intent对应源码分析
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
Log.e("zxy","the component is:::" + intent.getComponent());
//2021-01-17 14:08:34.780 10345-10345/com.example.activitylifecycle E/zxy: the component is:::ComponentInfo{com.example.activitylifecycle/com.example.activitylifecycle.SecondActivity}
可以看到,显式Intent的Component是有值的。
看源码:
public Intent(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
}
public Intent setClass(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
return this;
}
3、隐式Intent启动Activity
3.1 简介
隐式,不明确指定启动哪个Activity,而是设置Action、Data、Category,让系统来筛选出合适的Activity。即根据所有的< intent-filter >来筛选。
3.2 使用方式
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.second" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
MainActivity.java
Intent intent = new Intent("android.intent.action.second");
startActivity(intent);
Log.e("zxy","the component is:::" + intent.getComponent()); //null
SecondActivity.java
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.e("zxy", "SecondActivity:::onCreate");
Log.e("zxy", "SecondActivity:::getIntent().getComponent()::" + getIntent().getComponent());
}
2021-01-17 14:22:32.992 14804-14804/com.example.activitylifecycle E/zxy: MainActivity:::onCreate
2021-01-17 14:22:32.997 14804-14804/com.example.activitylifecycle E/zxy: MainActivity:::onResume
2021-01-17 14:22:34.111 14804-14804/com.example.activitylifecycle E/zxy: the component is:::null
2021-01-17 14:22:34.116 14804-14804/com.example.activitylifecycle E/zxy: MainActivity:::onPause
2021-01-17 14:22:34.150 14804-14804/com.example.activitylifecycle E/zxy: SecondActivity:::onCreate
2021-01-17 14:22:34.150 14804-14804/com.example.activitylifecycle E/zxy: SecondActivity:::getIntent().getComponent()::ComponentInfo{com.example.activitylifecycle/com.example.activitylifecycle.SecondActivity}
2021-01-17 14:22:34.152 14804-14804/com.example.activitylifecycle E/zxy: SecondActivity:::onResume
可以看出,通过隐式方式启动 Activity 的话,在第一个Activity中,其component值为null;而在SecondActivity中,其component值不为空。
那么隐式Intent的Component的值是在哪里赋予的呢ÿ