在 Android 中,界面的跳轉(zhuǎn)通常是通過啟動不同的 Activity 來實現(xiàn)的,下面介紹一下 Activity 的啟動方法。
顯式調(diào)用
顯式調(diào)用,字面意思即”明顯的調(diào)用“,我們可以在調(diào)用方法中明確的知道我們即將啟動的 Activity,顯式調(diào)用的具體方法如下:
val intent = Intent(this, SecondActivity::class.java)
// SecondActivity::class.java 相當(dāng)于Java中的 SecondActivity.class
startActivity(intent)
我們需要構(gòu)建一個 Intent 對象,第一個參數(shù)傳入 this 即當(dāng)前 Activity 的上下文,第二個對象傳入 SecondActivity::class.java 作為目標 Activity,這樣我們的意圖就很明顯,即我們想跳轉(zhuǎn)到 SecondActivity 這個界面,我們只需要調(diào)用 startActivity 這個函數(shù)就可以達到我們的目的了。
隱式調(diào)用
隱式調(diào)用與顯式調(diào)用相反,它沒有明確的說明要跳轉(zhuǎn)到哪個 Activity,而是通過 action, category [?k?t?ɡ?ri] 和 data 這三個過濾信息由系統(tǒng)去匹配復(fù)合條件的 Activity。
為 Activity 設(shè)置過濾信息
如果我們想要通過隱式調(diào)用去啟動一個 Activity,我們首先要為這個 Activity 設(shè)置過濾信息,否則是不能通過隱式調(diào)用去啟動這個 Activity 的。過濾信息在 AndroidMainfest.xml 文件中注冊 Activity 時設(shè)置,通過在 <activity> 標簽下配置<intent-filter> 的內(nèi)容,可以指定當(dāng)前Activity能夠響應(yīng)的action,category和data。
<activity
android:name=".activity.SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="room.join"
android:scheme="bjhlliveapp" />
</intent-filter>
</activity>
當(dāng)使用隱式調(diào)用啟動 Activity 時,需要同時匹配 action,category 和 data,否則匹配失敗。一個 <intent-filter>下的 action,category 和 data 可以有多個,一個 activity 可以有多個 <intent-filter> 標簽,只要成功匹配其中任意一個<intent-filter>中的信息即可匹配成功。
下面詳細說明一下各種信息的匹配規(guī)則。
action
action 是一個字符串(區(qū)分大小寫),系統(tǒng)已經(jīng)為我們預(yù)定義了一些 action,如 android.intent.action.MAIN 等,同時我們也可以自己定義 action,一個<intent-filter> 下可以有多個 action。
當(dāng)我們使用隱式調(diào)用時 Intent 中必須指定 action,當(dāng) action 和 activity 的 <intent-filter> 中任意一個 action 相同(字符串的值相同)時,匹配成功。
category
category 和 action 一樣是一個字符串,同時系統(tǒng)中有定義的 category,我們也可以自己定義 category,但是如果想讓一個 activity 支持隱式調(diào)用,那么必須在<intent-filter> 中指定 “android.intent.category.DEFAULT” 這個 category。
category 的匹配規(guī)則與 action 不同,隱式調(diào)用時 Intent 中必須指定 action,但可以沒有 category,但是如果指定了 category (可以是一個或多個),那么所有指定的 category 都要和<intent-filter> 中的 category 相同,否則匹配失敗。
用通俗的話來講,category 你可以不指定(如果不指定一定可以匹配成功),但是一旦你指定了,你就要保證你指定的這些 category 都要和你即將啟動的 activity 中某一個 <intent-filter> 中的category 相同。
為什么不指定反而可以匹配成功呢?因為前面說了如果 activity 支持隱式調(diào)用,則一定要有 “android.intent.category.DEFAULT” 這個 category,系統(tǒng)在調(diào)用 startActivity 或者 startActivityForResult 的時候會默認為 Intent 加上 “android.intent. category.DEFAULT” 這個category,所以可以匹配成功。
data
data 的語法結(jié)構(gòu)如下:
<data
android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string" />
data 由兩部分組成,mimeType 和 URI。mimeType 指媒體類型,比如image/jpeg、audio/mpeg4-generic 和 video/* 等,可以表示圖片、文本、視頻等不同的媒體格式,而URI中包含的數(shù)據(jù)就比較多了,下面是URI的結(jié)構(gòu):
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
例如:
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
URI 中每個數(shù)據(jù)的含義如下:
Scheme:URI 的模式,比如http、file、content 等,如果 URI 中沒有指定scheme,那么整個 URI 的其他參數(shù)無效,這也意味著 URI 是無效的。
Host:URI 的主機名,比如 www.baidu.com,如果 host 未指定,那么整個 URI 中的其他參數(shù)無效,這也意味著 URI 是無效的。
Port:URI 中的端口號,比如80,僅當(dāng) URI 中指定了 scheme 和 host 參數(shù)的時候 port 參數(shù)才是有意義的。
path、pathPattern 和 pathPrefix:這三個參數(shù)表述路徑信息,其中 path 表示完整的路徑信息;pathPattern 也表示完整的路徑信息,但是它里面可以包含通配符 “”,“” 表示0個或多個任意字符,需要注意的是,由于正則表達式的規(guī)范,如果想表示真實的字符串,那么“*” 要寫成“*”, “\”要寫成“ \\”;pathPrefix 表示路徑的前綴信息。
data 的匹配規(guī)則較為復(fù)雜,但總的來說就是 Intent 中的 data 必須和 <intent-filter> 中的一致,如果 <intent-filter> 中沒有,則 Intent 也沒有,如果 <intent-filter> 中有,則 Intent 中必須有切必須和 <intent-filter> 中相同。
調(diào)用方法
val intent = Intent("android.intent.action.CPW")
// intent 構(gòu)造函數(shù)指定 action
intent.addCategory("android.intent.category.DEFAULT")
// addCategory 方法指定category
intent.setDataAndType(Uri.parse("file://abc"), "text/plain")
// setDataAndType 方法指定data,參數(shù)為 URI 和 mimeType
startActivity(intent)
以上就是關(guān)于 Activity 啟動方法的全部內(nèi)容了!
歡迎微信搜索關(guān)注公眾號:Android沒有煩惱
一起學(xué)習(xí)更多Android知識