前言
安卓有兩種方式啟動(dòng)Activity农渊,一種是顯示啟動(dòng),另外一種是隱式啟動(dòng)或颊。顯示啟動(dòng)我們?cè)陧?xiàng)目中經(jīng)常用到砸紊,大家也都比較熟悉。今天我們主要講解一下隱式啟動(dòng)囱挑。隱式啟動(dòng)常用于不同應(yīng)用之間的跳轉(zhuǎn)(例如打開支付寶微信的支付頁(yè)面)醉顽,也可用于H5與native之間的交互。隱式啟動(dòng)就是action平挑,category和data的匹配游添,我們先來(lái)說(shuō)下匹配的規(guī)則,然后通過(guò)具體的例子去驗(yàn)證通熄。
匹配規(guī)則
- action的匹配規(guī)則
- action在Intent-filter可以設(shè)置多條
- intent中必須指定action否則匹配失敗且intent中action最多只有一條
- intent中的action和intent-filter中的action必須完全一樣時(shí)(包括大小寫)才算匹配成功
- intent中的action只要與intent-filter其中的一條匹配成功即可
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="com.jrmf360.action.ENTER"/>
<action android:name="com.jrmf360.action.ENTER2"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
下面的兩個(gè)intent都可以匹配上面MainActivity的action規(guī)則
Intent intent = new Intent("com.jrmf360.action.ENTER");
startActivity(intent);
Intent intent2 = new Intent("com.jrmf360.action.ENTER2");
startActivity(intent2);
- category的匹配規(guī)則
- category在intent-filter中可以有多條
- category在intent中也可以有多條
- intent中所有的category都可以在intent-filter中找到一樣的(包括大小寫)才算匹配成功
- 通過(guò)intent啟動(dòng)Activity的時(shí)候如果沒(méi)有添加category會(huì)自動(dòng)添加android.intent.category.DEFAULT唆涝,如果intent-filter中沒(méi)有添加android.intent.category.DEFAULT則會(huì)匹配失敗
- data的匹配規(guī)則
在說(shuō)data的匹配規(guī)則之前我們先來(lái)說(shuō)說(shuō)data的語(yǔ)法
<data
android:host="string"
android:mimeType="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:port="string"
android:scheme="string"/>
舉個(gè)栗子
scheme://host:port/path|pathPrefix|pathPattern
jrmf://jrmf360.com:8888/first
scheme:主機(jī)的協(xié)議部分,如jrmf
host:主機(jī)部分唇辨,如jrmf360.com
port: 端口號(hào)廊酣,如8888
path:路徑,如first
pathPrefix:指定了部分路徑赏枚,它會(huì)跟Intent對(duì)象中的路徑初始部分匹配亡驰,如first
pathPattern:指定的路徑可以進(jìn)行正則匹配,如first
mimeType:處理的數(shù)據(jù)類型嗡贺,如image/*
- intent-filter中可以設(shè)置多個(gè)data
- intent中只能設(shè)置一個(gè)data
- intent-filter中指定了data隐解,intent中就要指定其中的一個(gè)data
- setType會(huì)覆蓋setData,setData會(huì)覆蓋setType诫睬,因此需要使用setDataAndType方法來(lái)設(shè)置data和mimeType
實(shí)例驗(yàn)證
新建兩個(gè)項(xiàng)目externalstart1和externalstart2煞茫,在externalstart1中添加幾個(gè)button,點(diǎn)擊button通過(guò)隱式啟動(dòng)打開externalstart2中的Activity
先來(lái)看看externalstart2中隱式啟動(dòng)的配置
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="com.jrmf360.action.ENTER"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="jrmf360.com"
android:port="8888"
android:scheme="jrmf"/>
</intent-filter>
</activity>
<activity android:name=".FirstActivity">
</activity>
<activity android:name=".SecondActivity">
</activity>
在externalstart2項(xiàng)目中共有三個(gè)Activity摄凡,分別為MainActivity续徽,F(xiàn)irstActivity和SecondActivity。externalstart1項(xiàng)目通過(guò)隱式啟動(dòng)跳轉(zhuǎn)到MainActivity亲澡,在MainActivity中通過(guò)隱式啟動(dòng)傳遞的路徑(path)來(lái)打開FirstActivity或者SecondActivity钦扭。MainActivity的代碼如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
parseData();
}
private void parseData() {
Uri data = getIntent().getData();
if (data != null){
String scheme = data.getScheme();
String host = data.getHost();
int port = data.getPort();
String path = data.getPath();
String query = data.getQuery();
String message = data.getQueryParameter("message");
Log.e(getClass().getSimpleName(),"scheme:"+scheme);
Log.e(getClass().getSimpleName(),"host:"+host);
Log.e(getClass().getSimpleName(),"port:"+port);
Log.e(getClass().getSimpleName(),"path:"+path);
Log.e(getClass().getSimpleName(),"query:"+query);
if ("/first".equals(path)){
FirstActivity.intent(this,message);
finish();
}else if ("/second".equals(path)){
SecondActivity.intent(this,message);
finish();
}
}
}
}
當(dāng)path為first時(shí)跳轉(zhuǎn)到FirstActivity,path為second時(shí)跳轉(zhuǎn)到SecondActivity床绪,并打印data的各個(gè)部分日志客情;
在externalstart1中通過(guò)點(diǎn)擊按鈕來(lái)跳轉(zhuǎn)到externalstart2項(xiàng)目中其弊,下面看下externalstart1中按鈕的點(diǎn)擊邏輯:
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_firstActivity){
Intent intent = new Intent();
intent.setAction("com.jrmf360.action.ENTER");
intent.setData(Uri.parse("jrmf://jrmf360.com:8888/first?message=Hello FirstActivity"));
startActivity(intent);
}else if (id == R.id.btn_secondActivity){
Intent intent = new Intent();
intent.setAction("com.jrmf360.action.ENTER");
intent.setData(Uri.parse("jrmf://jrmf360.com:8888/second?message=Hello SecondActivity"));
startActivity(intent);
}else if (id == R.id.btn_mainActivity){
Intent intent = new Intent("com.jrmf360.action.ENTER");
intent.setData(Uri.parse("jrmf://jrmf360.com:8888"));
startActivity(intent);
}
}
根據(jù)按鈕的名字很容易看出各個(gè)按鈕需要跳轉(zhuǎn)到的Activity。
下面做點(diǎn)擊測(cè)試:
- 點(diǎn)擊btn_mainActivity
會(huì)跳轉(zhuǎn)到MainActivity膀斋,我們就看下打印的日志梭伐,就不貼頁(yè)面了
07-27 17:38:14.224 6568-6568/com.jrmf360.externalstart2 E/MainActivity: scheme:jrmf
07-27 17:38:14.224 6568-6568/com.jrmf360.externalstart2 E/MainActivity: host:jrmf360.com
07-27 17:38:14.224 6568-6568/com.jrmf360.externalstart2 E/MainActivity: port:8888
07-27 17:38:14.224 6568-6568/com.jrmf360.externalstart2 E/MainActivity: path:/
07-27 17:38:14.224 6568-6568/com.jrmf360.externalstart2 E/MainActivity: query:null
可以看到path和query都為空
- 點(diǎn)擊btn_firstActivity
會(huì)先跳轉(zhuǎn)到MainActivity頁(yè)面然后根據(jù)傳遞的path再打開FirstActivity,看下日志
07-27 17:39:49.145 6568-6568/com.jrmf360.externalstart2 E/MainActivity: scheme:jrmf
07-27 17:39:49.145 6568-6568/com.jrmf360.externalstart2 E/MainActivity: host:jrmf360.com
07-27 17:39:49.145 6568-6568/com.jrmf360.externalstart2 E/MainActivity: port:8888
07-27 17:39:49.145 6568-6568/com.jrmf360.externalstart2 E/MainActivity: path:/first
07-27 17:39:49.145 6568-6568/com.jrmf360.externalstart2 E/MainActivity: query:message=Hello FirstActivity
從日志中看到path為First仰担,query為message=Hello FirstActivity糊识,因此會(huì)打開FirstActivity并把message Hello FirstActivity傳遞過(guò)去。
- 點(diǎn)擊btn_secondActivity
會(huì)先跳轉(zhuǎn)到MainActivity頁(yè)面然后根據(jù)傳遞的path再打開SecondActivity摔蓝,看下日志:
07-27 17:41:56.712 6568-6568/com.jrmf360.externalstart2 E/MainActivity: scheme:jrmf
07-27 17:41:56.712 6568-6568/com.jrmf360.externalstart2 E/MainActivity: host:jrmf360.com
07-27 17:41:56.712 6568-6568/com.jrmf360.externalstart2 E/MainActivity: port:8888
07-27 17:41:56.712 6568-6568/com.jrmf360.externalstart2 E/MainActivity: path:/second
07-27 17:41:56.712 6568-6568/com.jrmf360.externalstart2 E/MainActivity: query:message=Hello SecondActivity
07
從日志中看到path為second赂苗,query為message=Hello SecondActivity,因此會(huì)打開SecondActivity并把message Hello SecondActivity傳遞過(guò)去贮尉。
其它事項(xiàng)
- android.intent.action.MAIN :程序最先啟動(dòng)的Activity可以給多個(gè)Activity設(shè)置
- android.intent.category.LAUNCHER:應(yīng)用程序是否顯示在桌面拌滋,可以給多個(gè)Activity配置
- android.intent.action.MAIN和android.intent.category.LAUNCHER同時(shí)設(shè)置會(huì)在launcher顯示一個(gè)應(yīng)用圖標(biāo),單獨(dú)設(shè)置android.intent.category.LAUNCHER不會(huì)出現(xiàn)圖標(biāo)绘盟,且一個(gè)應(yīng)用程序最少要有一對(duì)鸠真。也可以設(shè)置多對(duì),這樣會(huì)在系統(tǒng)桌面出現(xiàn)過(guò)個(gè)應(yīng)用程序圖標(biāo)龄毡。
隱式啟動(dòng)的知識(shí)點(diǎn)就講完了,更多應(yīng)用新姿勢(shì)等待您的挖掘锡垄。