安卓Activity隱式啟動(dòng)全面解析

前言

安卓有兩種方式啟動(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ī)則

  1. 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);
  1. 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ì)匹配失敗
  1. 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)

  1. android.intent.action.MAIN :程序最先啟動(dòng)的Activity可以給多個(gè)Activity設(shè)置
  2. android.intent.category.LAUNCHER:應(yīng)用程序是否顯示在桌面拌滋,可以給多個(gè)Activity配置
  3. 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ì)等待您的挖掘锡垄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沦零,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子货岭,更是在濱河造成了極大的恐慌路操,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件千贯,死亡現(xiàn)場(chǎng)離奇詭異屯仗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)搔谴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門魁袜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人敦第,你說(shuō)我怎么就攤上這事峰弹。” “怎么了芜果?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵鞠呈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我右钾,道長(zhǎng)蚁吝,這世上最難降的妖魔是什么旱爆? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮窘茁,結(jié)果婚禮上疼鸟,老公的妹妹穿的比我還像新娘。我一直安慰自己庙曙,他們只是感情好空镜,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捌朴,像睡著了一般吴攒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砂蔽,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天洼怔,我揣著相機(jī)與錄音,去河邊找鬼左驾。 笑死镣隶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诡右。 我是一名探鬼主播安岂,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼帆吻!你這毒婦竟也來(lái)了域那?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤猜煮,失蹤者是張志新(化名)和其女友劉穎次员,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體王带,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淑蔚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愕撰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刹衫。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盟戏,靈堂內(nèi)的尸體忽然破棺而出绪妹,到底是詐尸還是另有隱情,我是刑警寧澤柿究,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布邮旷,位于F島的核電站,受9級(jí)特大地震影響蝇摸,放射性物質(zhì)發(fā)生泄漏婶肩。R本人自食惡果不足惜办陷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望律歼。 院中可真熱鬧民镜,春花似錦、人聲如沸险毁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畔况。三九已至鲸鹦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跷跪,已是汗流浹背馋嗜。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吵瞻,地道東北人葛菇。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像橡羞,于是被迫代替她去往敵國(guó)和親眯停。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 的活動(dòng)是可以包含用戶界面的組件尉姨,主要用于與用戶進(jìn)行交互庵朝。 1 手動(dòng)創(chuàng)建活動(dòng) 手動(dòng)創(chuàng)建活動(dòng)可以加深對(duì)...
    deniro閱讀 3,600評(píng)論 0 10
  • 前言 我們?cè)陂_發(fā)一個(gè)app時(shí),最常用到的是通過(guò)Intent設(shè)置組件類名又厉,然后啟動(dòng)相應(yīng)的Activity。這種通過(guò)為...
    健忘仙森閱讀 3,894評(píng)論 0 3
  • 1. 什么是Activity Activity負(fù)責(zé)UI元素的加載與頁(yè)面之前的跳轉(zhuǎn)椎瘟,代表了一個(gè)頁(yè)面單元覆致。 2. Ac...
    付凱強(qiáng)閱讀 509評(píng)論 0 0
  • Intent組件雖然不是四大組件,但卻是連接四大組件的橋梁肺蔚,學(xué)習(xí)好這個(gè)知識(shí)煌妈,也非常的重要。 一宣羊、什么是Intent...
    困惑困惑困惑閱讀 1,496評(píng)論 0 0
  • 不知道從什么時(shí)候開始璧诵,還是一直是這樣,行動(dòng)力總是間歇性降為零仇冯,畏難之宿,慵懶,隨性苛坚。不到最后關(guān)頭比被,不采取行動(dòng)色难,得過(guò)且過(guò)...
    延小狼閱讀 171評(píng)論 0 3