Intent ---> 一個(gè)萬能的信使

Intent的奧秘

Intent稱為信使簡(jiǎn)直在形象不過了逃片。
隨著Android開發(fā)經(jīng)驗(yàn)的增長空郊,慢慢隨著時(shí)間的積累靴跛,我們會(huì)很自然的發(fā)現(xiàn)一些讓人佩服的東西缀雳,Intent就是其中一個(gè)。
我現(xiàn)在看見這個(gè)關(guān)鍵字梢睛,腦子里立馬浮現(xiàn)出古代的信鴿肥印、欽差。傳遞信息绝葡、傳遞動(dòng)作深碱。
今天我們就根據(jù)它的特性延伸一下,來解決項(xiàng)目中的需求藏畅。

Intent的應(yīng)用詳解

這塊是本文最關(guān)鍵敷硅,也是最基本的知識(shí)
不太明白的朋友我推薦一篇很詳細(xì)的博文

萬能信使的誕生

那現(xiàn)在就進(jìn)入主題吧。為什么這么叫呢榜旦?
先賣個(gè)關(guān)子幽七!在這個(gè)產(chǎn)品橫行的時(shí)代,在他們的’督促‘下溅呢,我們程序員不停的在進(jìn)化澡屡。至少我們知
一下幾點(diǎn):

  1. 代碼不能寫死,隨時(shí)準(zhǔn)備著改咐旧;
  2. 客戶端的功能最好能讓服務(wù)端控制驶鹉;
  3. 隨時(shí)準(zhǔn)備重構(gòu)別人的代碼(已經(jīng)被產(chǎn)品送走了)

好了言歸正傳,我也是因?yàn)樯厦娴牡诙€(gè)原因做了這個(gè)事情铣墨。
直接用需求來說:這個(gè)界面用native去寫室埋,不用h5,但是我還要能在服務(wù)端控制這個(gè)頁面上的某些View的’行為’伊约。
也就是說有一個(gè)按鈕姚淆,我可以在服務(wù)端去控制它打開一個(gè)新Activity,還是一個(gè)網(wǎng)頁碱妆,還是預(yù)先定義好的某種行為肉盹。

也就是在這個(gè)時(shí)候我發(fā)現(xiàn)了萬能的信使Intent,正好能解決這種問題疹尾。
同時(shí)我也說明一下上忍,今天我只是講這種實(shí)現(xiàn)的方式骤肛,只是取其中的原理性東西來說。更多的idea窍蓝,更多的需求腋颠,只希望你看完后能有所啟示吧。

Demo源碼

項(xiàng)目在Github上:GitHub
順便簡(jiǎn)單介紹一下Demo:一次偶然的機(jī)會(huì)吓笙,扔物線的推薦下開始了使用Rxjava + Retrofit網(wǎng)絡(luò)庫淑玫,深深地迷上了它(我指的是它,而不是這個(gè)胖子面睛,哈哈~~)
這些代碼是我從整個(gè)項(xiàng)目里面摘出來的絮蒿,可能會(huì)有一些殘留,見諒哈叁鉴!我盡量處理干凈土涝。

萬能的Intent

先介紹Intent的跳轉(zhuǎn)規(guī)則:

/** 
 * 打電話
 * @param view 
 */
public void call(View view) {  
    Intent intent = new Intent(Intent.ACTION_CALL);  
    intent.setData(Uri.parse("tel:1234567890"));  
    startActivity(intent);  
} 
/** 
 * 打開指定網(wǎng)頁 
 * @param view 
 */  
public void invokeWebBrowser(View view) {  
    Intent intent = new Intent(Intent.ACTION_VIEW);  
    intent.setData(Uri.parse("http://www.google.com.hk"));  
    startActivity(intent);  
}

就上面這段代碼中intent.setData()的方法,里面需求傳入各種系統(tǒng)規(guī)定好的標(biāo)簽幌墓,按照這種規(guī)則去通過Uri.parse去按照規(guī)則解析但壮,從而獲得這種行為動(dòng)作。
那么我們?nèi)绾沃滥繕?biāo)是否接受這種前綴呢常侣?這就需要看一下目標(biāo)中<data/>元素的匹配規(guī)則了蜡饵。
在目標(biāo)<data/>標(biāo)簽中包含了以下幾種子元素,他們定義了url的匹配規(guī)則:
android:scheme 匹配url中的前綴胳施,除了“http”溯祸、“https”、“tel”...之外巾乳,我們可以定義自己的前綴
android:host 匹配url中的主機(jī)名部分您没,如“google.com”鸟召,如果定義為“*”則表示任意主機(jī)名
android:port 匹配url中的端口
android:path 匹配url中的路徑
我們看下面的這兩塊代碼胆绊,這是和Android瀏覽器之間交互的規(guī)則

<activity android:name=".TestActivity">  
    <intent-filter>  
        <action android:name="com.scott.intent.action.TARGET"/>  
        <category android:name="android.intent.category.DEFAULT"/>  
        <data android:scheme="scott" android:host="com.scott.intent.data" android:port="9090" android:path="/test"/>  
    </intent-filter>  
</activity> 
public void gotoTestActivity(View view) {  
    Intent intent = new Intent("com.scott.intent.action.TARGET");  
    intent.setData(Uri.parse("scott://com.scott.intent.data:9090/test"));  
    startActivity(intent);  
} 

我們用Intent調(diào)系統(tǒng)打電話為例:

順序圖

這些信息的中的標(biāo)簽都是系統(tǒng)自己定義的,那么我們需要解決自己的需求欧募,就要定義自己的規(guī)則压状。
下面我們一起來一步一定義我們自己的規(guī)則,來滿足我們的需求跟继。如果上面的系統(tǒng)規(guī)則不明白种冬,沒事。接著往下走舔糖,串起來就都明白了娱两。

自定義規(guī)則

直接打開一個(gè)Activity

首先,我們看一下Intent的源碼金吗,其中有一個(gè)parseUri方法十兢。
里面寫的很清楚趣竣,系統(tǒng)定義的規(guī)則開頭是以android-app開頭的,并且是以end結(jié)尾

     *     <tr><td><code>android-app://com.example.app/http/example.com/foo?1234<br/>#Intent;action=com.example.MY_ACTION;end</code></td>
     *         <td><table style="margin:0;border:0;cellpadding:0;cellspacing:0">
     *             <tr><td>Action: </td><td><code>com.example.MY_ACTION</code></td></tr>
     *             <tr><td>Data: </td><td><code>http://example.com/foo?1234</code></td></tr>
     *             <tr><td>Package: </td><td><code>com.example.app</code></td></tr>
     *         </table></td>
     *     </tr>

這是源碼中的一條規(guī)則

android-app://com.example.app/http/example.com/foo?1234#Intent;action=com.example.MY_ACTION;end

android-app:這部分表示系統(tǒng)規(guī)則的前綴旱物,所以在我們自己定義規(guī)則時(shí)需要將系統(tǒng)的屏蔽掉遥缕,以免沖突,所以我們現(xiàn)在用intent做以區(qū)分宵呛,并且表明這個(gè)規(guī)則是要生成Intent
#Intent而這一句則是規(guī)則真正的開始单匣,源碼中的一句i = uri.lastIndexOf("#");也就是從#開始到end才是我們需要自己定義的規(guī)則
Action就是我們要做的事,但是我們今天的需求是跳轉(zhuǎn)行為宝穗,所以這個(gè)用component

好了户秤,介紹完系統(tǒng)的規(guī)則,來看一下打開我們定義的某個(gè)Activity的規(guī)則

"intent:#Intent;component=com.alex.alexintentdemo/.ui.TestActivity;end"

component=com.alex.alexintentdemo/.ui.TestActivity這個(gè)我相信大家看了絕對(duì)眼熟逮矛,沒錯(cuò)虎忌,這個(gè)就是系統(tǒng)的規(guī)則,在New IntentsetComponent然后startActivity時(shí)橱鹏,需要填寫的膜蠢,告訴系統(tǒng)我要打開那個(gè)Activity

好了,既然規(guī)則寫好了莉兰,那么接下來我們?cè)俑鶕?jù)規(guī)則生成Intent挑围,去調(diào)用

剛才講的這一整體部分最好結(jié)合代碼去看,UriUtils解析自定義Uri的類

直接打開一個(gè)接受參數(shù)的Activity

這種直接打開Activity有點(diǎn)太low了糖荒,接下來杉辙,我們要解決怎么打開一個(gè)接受參數(shù)的Activity
首先,我們看一下系統(tǒng)的支持參數(shù)的源代碼

String key = Uri.decode(uri.substring(i + 2, eq));
if (uri.startsWith("S.", i)) {
        intent.putExtra(key, value);
  } else if (uri.startsWith("B.", i)) {
      intent.putExtra(key, Boolean.parseBoolean(value));
  } else if (uri.startsWith("b.", i)) {
      intent.putExtra(key, Byte.parseByte(value));
  } else if (uri.startsWith("c.", i)) {
      intent.putExtra(key, value.charAt(0));
  } else if (uri.startsWith("d.", i)) {
      intent.putExtra(key, Double.parseDouble(value));
  } else if (uri.startsWith("f.", i)) {
      intent.putExtra(key, Float.parseFloat(value));
  } else if (uri.startsWith("i.", i)) {
      intent.putExtra(key, Integer.parseInt(value));
  } else if (uri.startsWith("l.", i)) {
      intent.putExtra(key, Long.parseLong(value));
  } else if (uri.startsWith("s.", i)) {
      intent.putExtra(key, Short.parseShort(value));
    } else throw new URISyntaxException(uri, "unknown EXTRA type", i);

這樣我們可以看出捶朵,所有的基本類型都支持蜘矢,并且有一套完整的書寫規(guī)則:
我們常用的有下面三個(gè),其他的都支持

 S.xxx=[string];//字符串類型
 B.xxx=[boolean];//布爾型
 i.xxx=[int];//整型

所以我們傳參數(shù)的規(guī)則如下:

intent:#Intent;component=com.alex.alexintentdemo/.ui.Test2Activity;B.flag=true;S.name=大家好;i.code=1221;end

特別提示:每一條指令之間用综看;區(qū)分

直接打開Http/Https鏈接

這個(gè)就相對(duì)簡(jiǎn)單了品腹,看源碼,只是在Uri解析的時(shí)候區(qū)分一下http/https的前綴红碑。
規(guī)則直接下發(fā)鏈接就可以了舞吭。

服務(wù)端控制行為

只要在init或者開發(fā)App的時(shí)候從服務(wù)端取下這些規(guī)則,在點(diǎn)擊按鈕析珊,或者需要出發(fā)的時(shí)候調(diào)一下CommonUtils.jumpWithUri()就可以了

CommonUtils.jumpWithUri(MainActivity.this,“rule”);

可擴(kuò)展的需求

今天在這里只是自定義了打開Activity羡鸥。其實(shí),其余的方式都是一樣的忠寻,只要明白了這一點(diǎn)就能相通了惧浴。
我在這里先列出幾個(gè):

  1. 打開Fragment;
  2. WebView傳參數(shù)奕剃;
  3. 彈出Toseat衷旅;
  4. 等等哑姚,太多了,只要你想的到芜茵,只要你的規(guī)則能寫好叙量,一切都不是事。

后續(xù)我會(huì)慢慢給Demo里完善這些東西

結(jié)束

很感謝大家能閱讀完這篇博文九串,寫的不合理绞佩、不行清楚、有錯(cuò)誤猪钮,請(qǐng)?jiān)u論指出品山,我們共同學(xué)習(xí)成長。

版權(quán)聲明:本文為博主原創(chuàng)文章烤低,轉(zhuǎn)載請(qǐng)注明出處肘交。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扑馁,隨后出現(xiàn)的幾起案子涯呻,更是在濱河造成了極大的恐慌,老刑警劉巖腻要,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复罐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡雄家,警方通過查閱死者的電腦和手機(jī)效诅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趟济,“玉大人乱投,你說我怎么就攤上這事∏瓯啵” “怎么了戚炫?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾效。 經(jīng)常有香客問我嘹悼,道長叛甫,這世上最難降的妖魔是什么层宫? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮其监,結(jié)果婚禮上萌腿,老公的妹妹穿的比我還像新娘。我一直安慰自己抖苦,他們只是感情好毁菱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布米死。 她就那樣靜靜地躺著,像睡著了一般贮庞。 火紅的嫁衣襯著肌膚如雪峦筒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天窗慎,我揣著相機(jī)與錄音物喷,去河邊找鬼。 笑死遮斥,一個(gè)胖子當(dāng)著我的面吹牛峦失,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播术吗,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼尉辑,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了较屿?” 一聲冷哼從身側(cè)響起隧魄,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隘蝎,沒想到半個(gè)月后堤器,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡末贾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年闸溃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拱撵。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辉川,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拴测,到底是詐尸還是另有隱情乓旗,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布集索,位于F島的核電站屿愚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏务荆。R本人自食惡果不足惜妆距,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望函匕。 院中可真熱鬧娱据,春花似錦、人聲如沸盅惜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至结啼,卻和暖如春医吊,著一層夾襖步出監(jiān)牢的瞬間悬垃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饿敲,地道東北人莫湘。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓哄尔,卻偏偏與公主長得像振愿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子红选,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評(píng)論 25 707
  • 注:本文完全拷貝自https://developer.android.com/guide/components/i...
    RxCode閱讀 1,743評(píng)論 1 13
  • 永遇樂·京口北固亭[1]懷古 辛棄疾 千古江山甚侣,英雄無覓,孫仲謀處间学。舞榭歌臺(tái)殷费,風(fēng)流總被,雨打風(fēng)吹去低葫。斜陽草樹详羡,尋常...
    古詩新讀閱讀 706評(píng)論 0 0
  • 1. 明白觀點(diǎn)是如何形成的。像其他人一樣嘿悬,你不斷地從感官中接收數(shù)據(jù)進(jìn)行感知实柠,并具有在認(rèn)知中探索意義的天生驅(qū)動(dòng)力。這...
    梁夢(mèng)婷閱讀 275評(píng)論 0 1
  • 今天是第三周的第一天善涨,早上6點(diǎn)半在肖超老師的帶領(lǐng)下晨跑5公里窒盐,比上次用時(shí)縮短了。 上午讀完瑜伽經(jīng)钢拧,學(xué)習(xí)了卡瑪瑜伽蟹漓。...
    蔣開心閱讀 340評(píng)論 0 0