参考:
https://www.runoob.com/w3cnote/android-tutorial-intent-base.html
https://xxgblog.com/2013/09/08/android-intent/
1. Intent概述
Intent(意图)是四大组件间的枢纽,用于在四大组件间传递讯息。
2. 显式Intent与隐式Intent
2.1 显式Intent
- 通过组件名指定启动的组件,比如通过Intent的构造方法、Intent的setComponent方法、Intent的setClass/setClassName方法。
- 每次启动的组件只有一个
2.1.1 通过Intent的构造方法启动组件
启动MainActivity2这个Activity
Intent intent = new Intent(this, MainActivity2.class);
startActivity(intent);
2.1.2 通过setComponent方法启动组件
通过Intent的setComponent方法将Intent和Activity/Service关联,
通过startActivity/startService方法,可以启动另外一个应用中的Activity或者Service
实例化一个ComponentName,需要两个参数:第一个参数是发起操作的应用包名(包名在AndroidManifest.xml中注明),例如启动跳转操作的Activity所在包名;第二个参数是接受操作的组件的全限定类名(包名+类名),例如被启动的Activity或者Service的全限定类名。
ComponentName常见的构造函数有三个:
ComponentName(String pkg, String cls)
ComponentName(Context pkg, String cls)
ComponentName(Context pkg, Class<?> cls)
这里以最基础的ComponentName(String pkg, String cls)
为例
启动一个Activity:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.otherapp",
"com.example.otherapp.MainActivity2"));
startActivity(intent);
启动一个Service:
Intent it = new Intent();
it.setComponent(new ComponentName("com.example.otherapp",
"com.example.otherapp.MyService"));
startService(it);
另外两种构造函数的示例:
ComponentName componentName = new ComponentName(this.getPackageName(), "com.example.app016.SecondActivity");
// 或者ComponentName componentName = new ComponentName(this, "com.example.app016.SecondActivity");
// 或者ComponentName componentName = new ComponentName(this, SecondActivity.class);
注意:
如果要启动的其他应用的Activity不是该应用的入口Activity,那么在AndroidManifest清单文件中,该Activity节点一定要加上android:exported="true"属性,表示允许其他应用打开该Activity;对于Service也同样:
<activity
android:name="com.example.otherapp.MainActivity2"
android:exported="true" >
</activity>
<service
android:name="com.example.otherapp.MyService"
android:exported="true" >
</service>
2.1.3 通过setClass/setClassName方法启动组件
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.1.4 显式Intent总结
显式Intent通过Component可以直接设置需要调用的Activity类,可以唯一确定一个Activity,意图特别明确,所以是显式的。设置这个类的方式可以是Class对象(如SecondActivity.class),也可以是包名加类名的字符串(如”com.example.app016.SecondActivity”)。这个很好理解,在应用程序内部跳转界面常用这种方式。
2.2 隐式Intent
- 不指定组件名,而限定组件的Action、Data、Category等属性。当需启动组件时, 系统去查找各个app在AndroidManifest中注册的组件,筛选出满足条件的组件
- 当不止一个组件满足时, 会弹出一个对话框,让我们选择启动哪个组件(比如应用双开下,出现的让用户选择app的情形)
2.2.1 通过action找到组件
action是一个字符串,代表Intent要完成的一个抽象"动作"
2.2.1.1 通过setAction方法设置action
AndroidManifest.xml文件中配置<intent-filter>并且包含<action>
这里将action的name设成”abcdefg”
<activity android:name="com.example.app016.SecondActivity">
<intent-filter>
<action android:name="abcdefg"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
当需要通过Intent启动该Activity时:
Intent intent = new Intent();
intent.setAction("abcdefg");
startActivity(intent);
2.2.1.2 通过Intent的构造方法设置action
AndroidManifest.xml文件中配置<intent-filter>并且包含<action>
这里将action的name设成”abcdefg”
<activity android:name="com.example.app016.SecondActivity">
<intent-filter>
<action android:name="abcdefg"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
当需要通过Intent启动该Activity时:
Intent intent = new Intent("abcdefg");
startActivity(intent);
注意:
为了防止应用程序之间互相影响,Action的一般命名方式是包名+Action名,例如这里命名”abcdefg”就很不合理了,可以改成”com.example.app016.MyTest”。
2.2.2 通过data和extras找到组件
data和extras,即执行动作要操作的数据和传递到目标的附加信息
下面举一个与浏览器交互的例子:
1 /**
2 * 打开指定网页
3 * @param view
4 */
5 public void invokeWebBrowser(View view) {
6 Intent intent = new Intent(Intent.ACTION_VIEW);
7 intent.setData(Uri.parse("http://www.google.com.hk"));
8 startActivity(intent);
9 }
10 /**
11 * 进行关键字搜索
12 * @param view
13 */
14 public void invokeWebSearch(View view) {
15 Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
16 intent.putExtra(SearchManager.QUERY, "android"); //关键字
17 startActivity(intent);
18 }
详情参见https://developer.aliyun.com/article/610992
2.2.3 通过category找到组件
category:要执行动作的目标所具有的特质或行为归类
详情参见https://developer.aliyun.com/article/610992
2.2.4 通过type找到组件
type:要执行动作的目标Activity所能处理的MIME数据类型
例如:一个可以处理图片的目标Activity在其声明中包含这样的mimeType:
<data android:mimeType="image/*" />
在使用Intent进行匹配时,我们可以使用setType(String type)或者setDataAndType(Uri data, String type)来设置mimeType。
2.2.5 隐式Intent总结
隐式Intent,不像显式Intent那样直接指定需要调用的组件,而是设置Action、Data、Category,让系统来筛选出合适的组件。筛选是根据所有的<intent-filter>来筛选。
3. Intent的属性
详情参见:https://www.runoob.com/w3cnote/android-tutorial-intent-base.html
- ComponentName(组件名称)
- Action(动作)
- Category(类别)
- Data(数据)
- Type(MIME类型)
- Extras(额外)
- Flags(标记)