Android DevArt4:IntentFilter学习及深入~问题描述:在不指定具体action前提下,如果有两个以上的Activity,具有完全相同的intent-filter,项目同步是否会出现异常?程序运行是否会崩溃?

2023-04-24,,

概述:GitHub

IntentFilter意图过滤器,三种匹配规则:action、category、data
重点:过滤规则中必须设置 '<category android:name="android.intent.category.DEFAULT" />' ,否则不生效。
同样也说明了addCategory是一个叠加的属性。其源码内部是一个 ArraySet

先做几个演示:

入口Activity:

public class SelectFilterActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_filter);
} /**
* 通过自定义action跳转,不设置category(系统在startActivity/startActivityForResult时默认为Intent加上DEFAULT),设置相应的data
*
* @param view
*/
public void action1(View view) {
Intent intent = new Intent();
intent.setAction("com.action.123");
// intent.addCategory("");
//注意:不能先setData在setType,因为这两个方法彼此会清除对方的值,详见源码
intent.setDataAndType(Uri.parse("content://"), "text/plain");
startActivity(intent);
} /**
* 通过自定义action跳转,设置自定义category,设置相应的data
*
* @param view
*/
public void action2(View view) {
Intent intent = new Intent("com.action.1");
intent.addCategory("com.category.abc.2");
intent.setDataAndType(Uri.parse("http://www.baidu.com:8080"), "image/*");
startActivity(intent);
} /**
* 不设置action,设置自定义category,设置相应的data
   *
* @param view
*/
public void category1(View view) {
Intent intent = new Intent();
intent.addCategory("com.category.mif3");
intent.setDataAndType(Uri.parse("file://abc"), "video/*");
startActivity(intent);
}
}

相应的AndroidMenifest.xml中的过滤规则:(其中MyIntentFilterActivity1~5均为测试用的EmptyActivity)

<!-- Android意图过滤器 -->
<activity android:name=".Chapter1.intentfilter.SelectFilterActivity" />
<activity android:name=".Chapter1.intentfilter.MyIntentFilterActivity">
<intent-filter>
<!-- 区分大小写 -->
<action android:name="com.action.1" />
<action android:name="com.action.2" />
<!--
系统在startActivity或startActivityForResult时会默认为 Intent 加上DEFAULT ,
所以为了使我们新建的Activity能够接收隐式调用,就必须在intent-filter中添加DEFAULT的category属性
-->
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.category.abc.1" />
<category android:name="com.category.abc.2" />
<!-- 注:如果过滤规则中定义了data,那么Intent中也必须要定义可匹配的data -->
<!-- scheme 默认为content和file -->
<!-- 不通data标签中的scheme、mimeType属性通用,host、port不通用 -->
<data
android:host="www.jooy.top"
android:mimeType="image/*"
android:port="80"
android:scheme="http" />
<data
android:host="www.baidu.com"
android:port="8080"
android:scheme="content" />
</intent-filter>
</activity>
<activity android:name=".Chapter1.intentfilter.MyIntentFilterActivity2">
<intent-filter>
<action android:name="com.action.123" />
<!-- 要么自定义,要么用DEFAULT,否则隐式跳转失败,并抛出异常 ActivityNotFoundException -->
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="video/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity> <activity android:name=".Chapter1.intentfilter.MyIntentFilterActivity3">
<intent-filter>
<action android:name="com.action.mif3" />
<category android:name="android.intent.category.DEFAULT" /> <!-- 必须有 -->
<category android:name="com.category.mif3" />
<!-- scheme 默认值 content/file -->
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<activity android:name=".Chapter1.intentfilter.MyIntentFilterActivity4">
<intent-filter>
MyIntentFilterActivity3
</intent-filter>
</activity>
<activity android:name=".Chapter1.intentfilter.MyIntentFilterActivity5">
<intent-filter>
MyIntentFilterActivity3
</intent-filter>
</activity>

回归正文:

问题描述:
在不指定具体action前提下(Intent跳转时可以不setAction,但清单文件中必须有action的过滤 <action android:name="com.action.mif3"/>),
如果有多个Activity:MyIntentFilterActivity4,5和MyIntentFilterActivity3等的intent-filter完全相同
项目同步是否会出现异常?程序运行是否会崩溃?。
答案是程序不会崩溃,系统会从底部弹窗,按照清单文件注册Activity的顺序依次排列,Act3..Act4..Act5...,点击进入相应的Activity,
just like this:

可见,在隐式跳转中,如果不指定具体的action名称(字符串),而是intent仅通过category+data类型去找相应的activity的话,可能会返回来一个Activity的集合,也可能返回空,那么此时就需要PackageManager出场了。

PackageManager两个api:(1)resolveActivity 方法,如果找不到目标act就返回null。Intent中也有该API,效果相同;(2)queryIntentActivities方法:返回所有成功匹配的act信息。

而且,针对Service和BroadcastReceiver等组件,PM同样提供了类似的方法获取匹配信息,如queryIntentServices、queryBroadcastReceivers等方法。

还差点东西。。。

上面说列表显示顺序是按照menifest的配置顺序排列的,我们调换下顺序

MyIntentFilterActivity3→MyIntentFilterActivity4→MyIntentFilterActivity5

改为:

MyIntentFilterActivity5→MyIntentFilterActivity4→MyIntentFilterActivity3

GitHub

如果这篇随记对你有所帮助,请点个赞吧。发起进攻(  ´-ω ・)▄︻┻┳══━一

‧★,:*:‧\( ̄▽ ̄)/‧:*‧°★* 

Android DevArt4:IntentFilter学习及深入~问题描述:在不指定具体action前提下,如果有两个以上的Activity,具有完全相同的intent-filter,项目同步是否会出现异常?程序运行是否会崩溃?的相关教程结束。

《Android DevArt4:IntentFilter学习及深入~问题描述:在不指定具体action前提下,如果有两个以上的Activity,具有完全相同的intent-filter,项目同步是否会出现异常?程序运行是否会崩溃?.doc》

下载本文的Word格式文档,以方便收藏与打印。