展开说说:Android之Activity的intent-filter匹配

大家都知道Activity启动分为两种型,显式启动和隐式启动,显式启动是指定了被启动的Activity而隐式启动则是通过匹配intent-filter的过滤内容进行匹配。

显式启动相对简单明了Intent intent = new Intent(ActivitA.this, ActivityB.class);而隐式启动则需要Intent intentY = new Intent(); 然后给intentY 设置action、category、data过滤信息。因此本篇重点讨论隐式启动的匹配规则。

现在说说intent-filter匹配规则:

1、action、category、data 如果intent-filter中前面三者都定义了就需要分别匹配成功了才能启动对应的Activity;

2、具体规则

2.1 action,是一个字符串可以使用系统预定义的也可以自定义,一个intent-filter可能包含多个action,intent设置的action只需要匹配其中一个即为成功。

2.2 category也是一个字符串,可以使用系统预定义的也可以自定义,intent如果设置了category不管几个它必须是在被启动Activity的清单文件注册的intent-filter中定义了的,intent可以不设置category但设置了就必须是在intent-filter中category包含的,这样才会匹配成功。如果intent没有设置category也可以匹配成功,因为谷歌提供的startActivity和startActivityForResult方法都会自动为intent的category添加“android.intent.category.DEFAULT”,因此Activity的intent-filter中需要添加category - “android.intent.category.DEFAULT”。

2.3 data匹配,它由mimeType和URI两部分组成。

mimeType是媒体类型,如iamge/jpeg 、 video/*等,白是图片、视频等媒体格式。

URI则是由一组数据拼接而成,<scheme>://<host>:<port>/path/pathrefix/pathPattern 例如:

https://www.baidu.com.8080/image/img491

或者https://blog.csdn.net/Hidanchaofan/article/details/12 ,分别是:scheme - URI的模式例如http、https、file等;port - 端口号; path、pathrefix都表示完整路径信息但pathrefix可以包含通配符“*”,需注意正则表达式规范注意转义字符 ;pathPattern 表示路径的前缀信息,可以没有。

Data匹配规则要求Intent的data数据能够完全匹配过滤规则中某一个data。有些时候过滤规则只指定了mimeType没有指定URI,但要记住URI是由默认值的,就是content和file,所以即便过滤规则没有指定URI但Intent中URI必须设置为content或者file启动匹配成功。还有一定Intent的setData方法除了设置URI还会把mimeTpe置空,相反setType在设置mimeType同时也会把URI置空,因此想要既设置URI又设置mimeType必须调用setDataAndType方法。

Intent-filter中<data android:scheme=”file” android:host=”www.baidu.com”>等同于<data android:scheme=”file” /> <data android:host=”www.baidu.com”>,一起写和分开写效果相同。

隐式启动和显式启动相比自由度更高但失败的机率也更大,一旦有一处匹配错误就会报错ActivityNotFoundException:No Activity found to handleIntent,因此我们需要在使用隐式启动前需要判断是否有可以匹配的Activiyt。PackageManager和Intent的resolveactivity方法都可以进行判断并返回最佳匹配的Activity信息,如果返回null就是没有可以匹配的了。另外,PackageManager的queryIntentActivities方法能够以list集合的形式返回所有可以匹配的Activity信息。三个方法调用都需要传入一个FALG,我们呢直接选择AMCH_DEFAULT_ONLY 他只会返回在Intent-filter设置了<category android:name=”android.intent.category.DEFAULT”>的Activity,不言而喻这个category对隐式启动来说那是“必须的啊”。

最后多说一句,设置显式启动的class再设置多少隐式启动的Intent-filter都是徒劳的,一定会执行显式启动的设置。

才疏学浅,如有问题,欢迎指正,多谢。 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果你在AndroidActivity中设置了intent-filter和action,并且通过`getAction()`方法获取不到Action,可能是由于以下原因导致的: 1. 确保在设置intent-filter时,正确地指定了Action。例如,如果你的intent-filter中指定了`android.intent.action.MAIN`作为Action,则应该使用`Intent.ACTION_MAIN`进行匹配。 2. 确保在获取Intent对象后,立即调用`getAction()`方法。如果在其他方法(如`onCreate()`之外的方法)中调用此方法,可能会导致获取不到Action。 3. 如果你在启动Activity时没有设置Action,那么通过`getAction()`方法是无法获取到Action的。你可以尝试通过`hasExtra()`方法来检查Intent中是否包含指定的Action。 以下是一个示例代码,展示了如何设置intent-filter和Action,并获取Intent中的Action: 在AndroidManifest.xml中的Activity节点下添加intent-filter: ```xml <activity android:name=".YourActivity"> <intent-filter> <action android:name="com.example.ACTION_CUSTOM" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> ``` 在Activity中获取Intent中的Action: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); String action = intent.getAction(); if (action != null && action.equals("com.example.ACTION_CUSTOM")) { // 获取到自定义Action } else { // 未获取到自定义Action } } ``` 确保你在获取Intent的Action时,使用正确的Action常量或自定义的Action字符串。如果问题仍然存在,请检查你的代码逻辑和配置,确保一切设置正确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值