天天看點

Android的顯示意圖和隐式意圖總結

顯示意圖

簡而言之:

通過指定特定Activity的包名和類名開啟Activity

應用場景:

一般應用于本App内的activity間的跳轉。

XML配置資訊:

AndroidManifest.xml

<!--顯示意圖:舉例-->
        <activity
            android:name=".activity.intent.IntentOneActivity"
            android:launchMode="singleTop"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustPan" />
           

開啟方式:

//顯示意圖激活的四種可用方式
    private void jumpOne() {
        //方式一:快捷方式(推薦,常用)
        Intent intent = new Intent(this, IntentTwoActivity.class);

//        //方式二:面向元件
//        Intent intent = new Intent();
//        ComponentName cn = new ComponentName(this, IntentTwoActivity.class);
//        intent.setComponent(cn);

//        //方式三:設定Class方式
//        Intent intent = new Intent();
//        intent.setClass(this, IntentTwoActivity.class);

//        //方式四:設定ClassName方式(有兩種參數方式;傳入全類名(完整包名+類名))
//        Intent intent = new Intent();
//        //intent.setClassName(this, "包名.activity.intent.IntentOneActivity");
//        intent.setClassName("包名", "包名.activity.intent.IntentOneActivity");

        startActivity(intent);
    }
           

隐式意圖

通過指定一組動作或資料開啟一個Activity
  1. 開啟系統應用的某個界面(如:打電話、發短信、浏覽器等)
  2. 開啟某個應用的某個界面(需要對方應用提供其隐式配置資訊)
  3. 也可以用于自身應用界面的跳轉(顯示意圖更友善)

隐式意圖配置和使用有多種情況

1️⃣配置與使用方式 一

<!--隐式意圖的配置聲明 -->
        <activity android:name=".activity.intent.IntentTwoActivity">

           <!--配置1:隻配置了action和category-->
            <intent-filter>
                <!-- 預設的一種規範:全類名(包名+類名) -->
                <action android:name="包名.activity.intent.IntentTwoActivity" />
                <!--預設的一個category(必不可少)-->
                <category android:name="android.intent.category.DEFAULT" />

            </intent-filter>

            <!--配置2:mimeType-->
            <intent-filter>
                <action android:name="包名.myName" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.AA" />

                <data android:mimeType="ab/cd3" />
            </intent-filter>

            <!--配置3:隻有scheme有值-->
            <intent-filter>
                <action android:name="xx.xxx.xxx.xxx" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.aa" />

                <data android:scheme="abc" />
            </intent-filter>

            <!--配置4:mimeType和scheme 有值-->
            <intent-filter>
                <action android:name="wo.shi.yi.ge.action" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="xx.xxx.aa.bb" />

                <data
                    android:mimeType="a/b"
                    android:scheme="home" />
            </intent-filter>

        </activity>
           
  • 自身應用内使用隐式意圖激活
    • 比對:(上述)配置1
Intent intent = new Intent(); //建立意圖對象
        //為意圖設定 action(動作)
        intent.setAction("包名.activity.intent.IntentTwoActivity");
        //為意圖添加 category(類别)
        //category可以省略不加,intent 會預設為:"android.intent.category.DEFAULT"
        //intent.addCategory("android.intent.category.DEFAULT");
        startActivity(intent);
           
    • 比對:(上述)配置2
Intent intent = new Intent();
        intent.setAction("包名.myName");
        intent.addCategory("android.intent.category.AA");
        intent.setType("ab/cd3");
        startActivity(intent);
           
    • 比對:(上述)配置3
Intent intent = new Intent();
        intent.setAction("xx.xxx.xxx.xxx");
        intent.addCategory("android.intent.category.aa");
        intent.setData(Uri.parse("abc:"));
        startActivity(intent);
           
    • 比對:(上述)配置4
Intent intent = new Intent();
        intent.setAction("wo.shi.yi.ge.action");
        intent.addCategory("xx.xxx.aa.bb");
        intent.setDataAndType(Uri.parse("home:"), "a/b");
        startActivity(intent);
           

2️⃣配置與使用方式 二

  • intent-filter 多比對規則:當有多個 action,多個category,多個data,隻需要比對一組即可!
<!--隐式意圖的配置聲明 -->
        <activity android:name=".activity.intent.IntentTwoActivity">
            <intent-filter>
                <!-- action name:内容可以任意定義 -->
                <action android:name="包名.activity.intent.IntentTwoActivity" />
                <action android:name="包名.myName" />
                <action android:name="xx.xxx.xxx.xxx" />
                <action android:name="wo.shi.yi.ge.action" />
                <!--預設的一個category(必不可少),還可以自定義其他的-->
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.AA" />
                <category android:name="android.intent.category.aa" />
                <category android:name="xx.xxx.aa.bb" />
                <!--定義意圖的:限制和資料-->
                <data android:mimeType="ab/cd3" />
                <data android:scheme="abc" />
                <data
                    android:mimeType="a/b"
                    android:scheme="home" />
            </intent-filter>
        </activity>
           
    • 比對:(上述)配置

      注意: 若

      的配置資料裡面,有的比對規則隻配置了:mimeType,有的隻配置了:scheme,有的配置了:mimeType和scheme,那麼在激活設定的時候必須使用:setDataAndType()方法,參數内可以比對任意的:scheme和mimeType的資料!
Intent intent = new Intent();
        intent.setAction("wo.shi.yi.ge.action");
        intent.addCategory("xx.xxx.aa.bb");
        intent.setDataAndType(Uri.parse("abc:"), "ab/cd3");
        startActivity(intent);
           

兩個應用之間如何激活?

以上述:配置與使用方式 二 為比對規則,在其他應用内激活本應用的指定的某個activity(此處以:IntentTwoActivity 為例)

::使用 kotlin 代碼來實踐說明

代碼如示:

//action 和 addCategory 比對配置裡面的任意一個就可以
        //addCategory可以不傳值,intent會預設傳遞:android.intent.category.DEFAULT
        val intent = Intent()
        intent.action = "包名.activity.intent.IntentTwoActivity"
        intent.`package` = "包名"
        intent.addCategory("android.intent.category.AA")
        //錯誤
        //intent.data = Uri.parse("home:")
        //intent.type = "ab/cd3"
        //正确
        intent.setDataAndType(Uri.parse("home:"), "ab/cd3")
        startActivity(intent)
           

隐式意圖使用特别注意點:

  1. setType()和setData不能同時存在,兩個方法會互相清空對方的設定。若同時使用,會抛出異常!若需要同時設定類型和資料,可以使用setDataAndType()方法!
  1. 若AndroidManifest中意圖配置中隻配置了:android:mimeType,那麼隻能且必須使用setType()方法,不能使用setDataAndType()方法!
  1. 若AndroidManifest中意圖配置中隻配置了:android:scheme,那麼隻能且必須使用setData()方法,不能使用setDataAndType()方法!
  1. 若AndroidManifest中意圖配置中配置了:android:mimeType和android:scheme,那麼隻能且必須使用setDataAndType()方法!

注意一個坑: 下面的兩個方法,參數裡面的 ' : ' (就是這個冒号)千萬!千萬!不要忘記了~ (你懂的,說多了都是淚,我之前就是沒注意,然後Debug了好久,讓我記憶深刻啊!)

setData(Uri.parse("xx:"))

setDataAndType(Uri.parse("xx:"), "xx/xx")

intent-filter多種比對規則:需要注意如下

  • 多比對規則 配置在同一個...内
    • 如(上述):配置與使用方式 二,該情況下必須使用setDataAndType()方法設定資料,不能省略!
  • 多比對規則 配置在不同的...内
    • 如(上述):配置與使用方式 一,配置資料裡有多種比對規則,有的配置了mimeType,有的配置了scheme,有的配置了mimeType和scheme,還有的mimeType和scheme都沒有配置;那麼,在激活的時候,就可以根據需求使用不同的方式去激活。