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

概述: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

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

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

原文地址:https://www.cnblogs.com/jooy/p/8691443.html