【Android】Android基础--显式Intent和隐式Intent

2024-07-13 08:33:14 浏览数 (2)

Intent 分两种,显式 Intent 和隐式 Intent。如果一个 Intent 明确指定了要启动的组件的完整类名,那么这个 Intent 就是显式 Intent,否则就是隐式 Intent。

当我们用一个显式 Intent 去启动组件时,Android 会根据 Intent 对象所提供的 component name 直接找到要启动的组件,当我们用一个隐式的 Intent 去启动组件时,Android 系统就无法直接知道要启动的组件名称了。

显式 Intent​​​​​​​
代码语言:javascript复制
Intent intent = new Intent(this, xxx.class);startActivity(intent);
隐式 Intent

使用隐式 Intent 之前需要在 AndroidManifest.xml 中对标签增加设置。

代码语言:javascript复制
<activity android:name="..IntentActivity">    <intent-filter>        <action android:name="com.luyai.action.TEST" />    </intent-filter></activity>

使用隐式 Intent 跳转 Activity。​​​​​​​

代码语言:javascript复制
Intent intent = new Intent("com.luyai.action.TEST");startActivity(intent);
Intent Filter

如果 Intent 中的存在 category 那么所有的 category 都必须和 Activity 过滤规则中的 category 相同。才能和这个 Activity 匹配。Intent 中的 category 数量可能少于 Activity 中配置的 category 数量,但是 Intent 中的这 category 必须和 Activity 中配置的 category 相同才能匹配。

​​​​​​​

代码语言:javascript复制
<activity android:name=".ui.activity.IntentActivity">    <intent-filter>        <action android:name="com.luyai.action.TEST" />        <category android:name = "android.intent.category.DEFAULT" />        <category android:name="xxx.xxx.xxx"/>    </intent-filter></activity>

运行以下代码可以匹配到 IntentActivity:

​​​​​​​

代码语言:javascript复制
Intent intent = new Intent("com.luyai.action.TEST");intent.addCategory("xxx.xxx.xxx");startActivity(intent);

只通过 category 匹配是无法匹配到 IntentActivity 的,因为 category 属性是一个执行 Action 的附加信息。

URL Scheme

Android 中的 Scheme 是一种页面内跳转协议,是一种非常好的实现机制。通过定义自己的 Scheme 协议,可以非常方便跳转 App 中的各个页面。

使用场景:

  • 通过小程序,利用 Scheme 协议打开原生 App。
  • H5 页面点击锚点,根据锚点具体跳转路径 App 端跳转具体的页面。
  • App 端收到服务器端下发的 Push 通知栏消息,根据消息的点击跳转路径跳转相关页面。
  • App 根据URL跳转到另外一个 App 指定页面。
  • 通过短信息中的 URL 打开原生 App。 Scheme 路径的规则:
代码语言:javascript复制
<scheme> :// <host> : <port> [<path>|<pathPrefix>|<pathPattern>]

设置 Scheme

在 AndroidManifest.xml 中对标签增加设置 Scheme。

代码语言:javascript复制
<activity    android:name=".ui.activity.SchemeActivity"    android:screenOrientation="portrait">    <!--Android 接收外部跳转过滤器-->    <!--要想在别的 App 上能成功调起 App,必须添加 intent 过滤器-->    <intent-filter>        <!--协议部分配置,注意需要跟 web 配置相同-->        <data android:scheme="aa"            android:host="bb"            android:port="1024"            android:path="/from"/>        <!--下面这几行也必须得设置-->        <category android:name="android.intent.category.DEFAULT" />        <!--表示 Activity 允许通过网络浏览器启动,以显示链接方式引用,如图像或电子邮件-->        <category android:name="android.intent.category.BROWSABLE" />        <action android:name="android.intent.action.VIEW" />    </intent-filter></activity>

原生调用:

代码语言:javascript复制
Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);startActivity(intent);

网页调用:

代码语言:javascript复制
<a href="aa://bb:1024/from?type=jeanboy">打开 App</a>

在 SchemeActivity 中可以处理 Scheme 跳转的参数:

代码语言:javascript复制
public class SchemeActivity extends AppCompatActivity {
    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Uri uri = getIntent().getData();        if (uri != null) {            //获取指定参数值            String type = uri.getQueryParameter("type");            Log.e("SchemeActivity", "type:"   type);
            if(type.equals("jeanboy")){                ActivityUtils.startActivity(XXXActivity.class);            }else if(type.equals("main")){                ActivityUtils.startActivity(MainActivity.class);            }        }        finish();    }}

判断一个 Scheme 是否有效:​​​​​​​

代码语言:javascript复制
PackageManager packageManager = getPackageManager();Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);boolean isValid = !activities.isEmpty();if (isValid) {    startActivity(intent);}

0 人点赞