• 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

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

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

  • 相关阅读:
    Spring Boot
    Spring Boot
    Spring Boot
    Restful API
    Jenkins
    虚拟化
    SpringBoot入门
    System Workbench for STM32(based on Eclipse)开发环境配置
    装机总结
    这年暑假
  • 原文地址:https://www.cnblogs.com/jooy/p/8691443.html
Copyright © 2020-2023  润新知