概述: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
如果这篇随记对你有所帮助,请点个赞吧。发起进攻( ´-ω ・)▄︻┻┳══━一
‧★,:*:‧( ̄▽ ̄)/‧:*‧°★*