Android显式意图和隐式意图
Posted 我想月薪过万
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android显式意图和隐式意图相关的知识,希望对你有一定的参考价值。
intent基本理解
- 我们都知道android四大组件:Activity 、Service、broadcast receiver 及 内容提供者。
- 其中,Activity 、Service、broadcast receiver 三大组件之间的通信 intent 起着至关重要的作用,即 媒介。
- intent 可以激活 Android 应用的三个核心组件:活动(Activity)、服务(Service)和广播接收器(BroadcastReceiver)
显式意图 和 隐式意图
显示意图:在创建 intent 的时候明确指定了组件名,例如:调用 Intent.setComponent() 或Intent.setClass() 或 使用构造器来指定组件( new Intent(MainActivity.this, OtherActivity.class))
隐式意图:在创建 intent 的时候没有明确指定组件名,而是 系统根据 设置的 动作(action)、类别(category)、数据(data: URI和数据类型)找到最合适的组件来处理这个意图。
隐式意图代码示例
第一步:创建 SecondActivity
package com.wust.intenttest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.Nullable;
/**
* ClassName: SecondActivity <br/>
* Description: <br/>
* date: 2021/10/24 22:49<br/>
*
* @author yiqi<br />
* @QQ 1820762465
* @微信 yiqiideallife
* @技术交流QQ群 928023749
*/
public class SecondActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText("我是secondView");
setContentView(textView);
}
}
第二步:在 清单文件 中声明
<activity android:name=".SecondActivity">
<intent-filter>
<!-- 自定义的动作 一般前缀为包名-->
<action android:name="com.wust.intenttest.SECOND"/>
<!-- 附加信息 这个必须得加上-->
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
如果你在清单文件中 没有加 <category android:name="android.intent.category.DEFAULT"/> ,就会报如下错误,这是因为 你在调用 startActivity()的时候系统自动给你的意图添加了 android:name="android.intent.category.DEFAULT" 这个类别,所以你在清单文件中不声明,系统当然自动匹配不上,除非你不用隐式意图。
第三步:跳转代码
public void tz(View v) {
//这里我们使用隐式意图 所以不指明是哪个组件
Intent intent = new Intent();
intent.setAction("com.wust.intenttest.SECOND");
// 这个类别系统会自动添加
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
}
第四步:传递 Uri 数据
我们可以通过Intent的Data、Type、Extra传入一些数据,这些数据可以用于进一步筛选匹配Activity,打开指定的页面、文件,或者给准备启动的Activity传入需要的参数。
这个时候我们再新建一个 ThirdActivity.java
package com.wust.intenttest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.Nullable;
/**
* ClassName: ThirdActivity <br/>
* Description: <br/>
* date: 2021/10/25 9:57<br/>
*
* @author yiqi<br />
* @QQ 1820762465
* @微信 yiqiideallife
* @技术交流QQ群 928023749
*/
public class ThirdActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText("我是ThirdView");
setContentView(textView);
}
}
同时在 清单文件 中进行声明
<activity android:name=".SecondActivity">
<intent-filter>
<!-- 自定义的动作 一般前缀为包名-->
<action android:name="com.wust.intenttest.SECOND" />
<!-- 附加信息 这个必须得加上-->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".ThirdActivity">
<intent-filter>
<!-- 自定义的动作 一般前缀为包名-->
<action android:name="com.wust.intenttest.SECOND" />
<!-- 附加信息 这个必须得加上-->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
我们可以发现 我们注册 SecondActivity 和 ThirdActivity 的时候 给的筛选条件 action 、category 是一样的。所以但我们仍然执行第三步的跳转代码时,系统就会让我们进行选择了,运行效果如下图:
这个时候,我们的 data 筛选条件就起作用了,我们不妨在 ThirdActivity 声明的时候加上如下筛选条件:
<activity android:name=".ThirdActivity">
<intent-filter>
<!-- 自定义的动作 一般前缀为包名-->
<action android:name="com.wust.intenttest.SECOND" />
<!-- 附加信息 这个必须得加上-->
<category android:name="android.intent.category.DEFAULT" />
<!-- 自定义的scheme,还有别的属性,自行尝试 -->
<data android:scheme="http"/>
</intent-filter>
</activity>
这个时候,我们再 执行第三步的跳转代码 毫无疑问,当然是跳转到 SecondActivity。效果如下:
但是,这个效果并不是我要说的重点,我们重点是看如何通过 data 来传递 uri 数据。 所以,我们对 第三步 的跳转代码进行如下改造:
public void tz(View v) {
// 这里我们使用隐式意图 所以不指明是哪个组件
Intent intent = new Intent();
intent.setAction("com.wust.intenttest.SECOND");
// 这个类别系统会自动添加
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 设置数据
intent.setData(Uri.parse("http://121.0.0.1"));
startActivity(intent);
}
相应的 ThirdActivity 也得作出相应的接收
package com.wust.intenttest;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.Nullable;
/**
* ClassName: ThirdActivity <br/>
* Description: <br/>
* date: 2021/10/25 9:57<br/>
*
* @author yiqi<br />
* @QQ 1820762465
* @微信 yiqiideallife
* @技术交流QQ群 928023749
*/
public class ThirdActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText("我是ThirdView");
setContentView(textView);
Uri data = getIntent().getData();
System.out.println( "data.getHost() => " + data.getHost());
System.out.println( "data.getScheme() => " + data.getScheme());
}
}
运行效果如下:
所有对于 data 这个筛选项 我们搞清楚以下三个地方:
清单文件中
<data android:scheme="http" android:host="127.0.0.1" android:port="80" android:path="/mypath" android:mimeType="wust/yiqi"/>
跳转代码
intent.setDataAndType(Uri.parse("http://127.0.0.1:80/mypath"), "wust/yiqi");
获取数据代码
data.getScheme()://data.getHost():data.getPort()data.getPath()
显式意图
如果大家把上面的 隐式意图 搞清楚,显式意图简直就是小草一碟。
根据 显式意图 的定义,我们在创建 intent 的时候,明确那个要跳转的组件即可。
第一步:代码示例
public void tz(View v) {
// 这里我们使用显式意图 所以指明是哪个组件
Intent intent = new Intent(this,SecondActivity.class);
startActivity(intent);
}
第二步:传递 action 、category、data,请参考隐式意图
跳转代码
public void tz(View v) {
// 这里我们使用显式意图 所以指明是哪个组件
Intent intent = new Intent(this,SecondActivity.class);
intent.setAction("com.wust.intenttest.SECOND");
// 这个类别系统会自动添加
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 设置数据
intent.setDataAndType(Uri.parse("http://127.0.0.1:80/mypath"), "wust/yiqi");
startActivity(intent);
}
数据获取代码 在目标组件中编写,这里的目标组件为 SecondActivity
Uri data = getIntent().getData();
System.out.println("data.getHost() => " + data.getPath());
System.out.println("data.getScheme() => " + data.getScheme());
效果展示
以上是关于Android显式意图和隐式意图的主要内容,如果未能解决你的问题,请参考以下文章