Intent的那些些事兒,Intent些事兒

來源:互聯網
上載者:User

Intent的那些些事兒,Intent些事兒

  請原諒我用這麼文藝的標題來闡釋一顆無時無刻奔騰著的2B青年的心。可是今天要介紹的Intent絕不2B,甚至在我看來,或許還有些許飄逸的味道,至於飄逸在哪裡呢?那我們就好好來剖析剖析Intent和它的好搭檔IntentFilter的基友情。

開場告白

  Intent在Android大家庭中是一個活潑的小男孩,從小就是交際草。在代碼中,Activity、Service、BroadcastReceiver這三個重要的大媽級重量組件,之間的調用關聯都是依靠Intent去交流的,例如Activity的startActivity(),Service的startService()、bindService(),BroadcastReceiver的sendBroadcast()、sendOrderBroadcast()等,其中都是需要攜帶一個Intent(或IntentFilter)的參數。

  當然Intent中要指定要啟動組件的資訊,或明顯活隱晦。明顯的就是顯式啟動:舉個例子來說就是Intent你去把這東西交給某某(名字)Activity大媽。隱晦的是隱式啟動:當然得不免俗得給例子就是Intent你把這個東東交給昨晚和我一起在菜市場跳廣場舞的那個胖大媽,其中廣場舞和胖就把某大媽給赤果果的定位了。這就是Intent的兩種匹配方式,我都覺得我自己說的怪抽象的了。

  接下來就是介紹IntentFilter的好時機了,它就是大媽的兒子(組件的攔截器)。當如果Intent隱式啟動時,Intent會找他的一群小夥伴IntentFilter來,然後問他們說,你們誰的媽昨晚去菜市場跳廣場舞了?你們誰的媽又好胖好胖的?然後IntentFilter各想各媽,哎呀,其中一個IntentFilter拍拍腦袋說,這不就是我媽嗎!然後他就屁顛屁顛的領著Intent去找某Activity媽把東東交給她了。

  為了避免大家看不懂上面的例子,我還是發揚一下2B青年的社會責任感,用比較教條的語言來介紹一下Intent和IntentFilter:Intent是一個意圖對象,組件可以通過設定Intent來啟動另外一個組件,有顯式啟動和隱式啟動兩種方法,顯式啟動直接指定要啟動的組件的名字,隱式啟動則指定action、category、data等來啟動合格組件;其中的IntnetFilter就是一個意圖過濾器,它會設定一些過濾規則如action、category、data等,如果Intent中的action、category、data與過濾器中相匹配,則為啟動該過濾器的組件。

碼點代碼

  攻城獅的思維就是不見代碼不給贊,所以我還是得老老實實得碼幾個代碼出來撐撐場子。但是Intent的顯式啟動和隱式啟動代碼度娘一下幾大頁,在這裡再貼上來就對不起人民群眾了。所以呢,我就記錄點關鍵代碼,如果後面犯失憶了也可以回來偵查一下容易忘的知識。

顯式啟動Activity、Service:

Intent intent1 = new Intent(getApplicationContext(), MyActivity.class);startActivity(intent1);//啟動Activity組件startActivityForResult(intent1, 1);//啟動有返回的Activity
Intent intent2 = new Intent(getApplicationContext(), MyService.class);startService(intent2);//啟動ServicebindService(intent2, conn, 1);//綁定Service

隱式啟動Activity、Service:

Intent intent1 = new Intent();intent1.setAction("com.net168.test.action.myactivity");startActivity(intent1);//啟動Activity組件Intent intent2 = new Intent();       intent1.setAction("com.net168.test.action.myservice");startService(intent2);//啟動ServicebindService(intent2, conn, 1);//綁定Service

發送廣播:

Intent intent = new Intent();intent.setAction("com.net168.test.action.mybroadcast");sendBroadcast(intent);//發送普通廣播sendOrderedBroadcast(intent, null);//發送有序廣播

其實很簡單,簡單得我這的不好意思介紹了。。。

 Intent的家世於IntentFilter的糾結

  Intent的背景很複雜,複雜到比一些不入流的HEI社會還複雜些。大體來說,Intent大致包含了Component、Action、Categroy、Data、Type、Extra和Flag這七大金剛(屬性),後面我們就好好解釋這些大哥大姐們。

Component:它需要接受一個ComponentName的對象,建立一個ComponentName需要指定包名和類名--這就唯一確定了一個組件類,這樣程式就可以通過給定的組件類去啟動相應的組件;所以我們可以從這裡重新給顯式啟動和隱式啟動分個類,一般如果明確指定ComponentName時就是顯式啟動,反之就是隱式啟動。另外我們可以直接在執行個體化Intent時在建構函式中傳入上下文和類名也可以直接幫我們設定了ComponentName,如Intent(this,MyActivity.class),推薦這種方式,比較簡潔。

Action:Action要完成一個抽象的動作,但具體由哪個組件來完成則不確定,需要根據IntentFilter來確定組件;在Intent中,Action最多隻能有1個,而在IntentFilter中Action可以有多個。這是隱式啟動一個組件最基礎的屬性。

Category:它為Action增加額外的類別資訊,因為Action可以啟動到多個組件,但是如果往下更詳細的分析要啟動的組件,可以通過Category來進行攔截;在IntentFilter和Intent中Category可以有多個。任何一個IntentFilter的預設存在一個Intent.CATEGORY_DEFAULT的屬性。

Data、Type:這兩個算是比較親的屬性。

  Data屬性通常用於向Action提供操作的資料,其值為一個Uri對象,Uri對象滿足 scheme://host:port/path 的格式,如 content://com.android.contacts/contacts/1,其中content是scheme的部分、com.android.contacts是host的部分、port部分被省略、contacts/1是path的部分。

  Type屬性用於指定該Data所指定Uri對應的MIME類型,可以是所以自訂的類型,只要符合abc/xyz格子的字串即可。

在使用中,我們要知道這兩個屬性會相互覆蓋:如果Intent先設定Data屬性,後設定的Type屬性將會把Data屬性覆蓋掉,反之同理。所以如果要設定Data和Type屬性的話需要調用Intent的setDataAndType()的方法。

Extra:Extra是用於多量的資料交換,它的對象是一個Bundle對象。

Flag:Flag屬性是為了該Intent添加一些額外的控制旗標,可以通過addFlag()添加控制旗標,通常可以通過它來控制Activity的啟動效果和啟動方式。

這七個屬性中,Intent與IntnetFilter匹配的匹配規則在在於Action、Category、data、Type這幾個屬性中,具體規則如下:

Action的匹配規則:

1、如果Intent中包含action_A,而在IntentFilter中只要存在action_A這個字串,無論是否還有其他的action_B、action_C,這個Intent都能被IntnetFilter成功匹配。

2、如果如果Intent中包含action_A,只要IntnetFilter中不存在action_A的話,IntentFilter就不能匹配到Intnet。

3、如果Intent中不存在任何action_x,只要IntnetFilter中存在任意一個action_x的話,Filter就能匹配上Intent。

4、如果IntentFilter不存在任何action_x,則無論Intent中無論存在任何action_x或者沒有任何action_x的話,兩者是完全不能匹配上的。

Category的匹配規則:

  這個匹配關係較為簡單,只要Intent中所有category在IntentFilter中都存在,則Intent可以匹配上IntnetFilter,不論此時Intentfilter中還存在其它的category。舉個例子,如果Intent中存在category_A、category_B,而Intentfilter中存在category_A、category_B、category_C,則可以匹配;如果而Intentfilter中存在category_A、category_D、category_C,因為Intentf中不存在Intent中存在的category_B,所以匹配失敗。

Data和Type的匹配規則:

data由URI來描述和定位,URI由三部分組成,scheme://host:port/path  模式://主機:連接埠/路徑

此外在事件中,還可以設定data的MIME類型,作為事件的datatype屬性。

首先明確一個匹配原則,就是對於URI的匹配,只比較IntentFilter中聲明的部分。

部分匹配原則:只要IntentFilter中聲明的部分匹配成功,就認為整個URI匹配成功。

舉例來說,     content://com.silenceburn.SdCardTester:1000/mydata/private/

和IntentFilter定義為  content://com.silenceburn.SdCardTester:1000/     是可以匹配的。

注意IntentFilter中並沒有定義path部分,但是依然可以匹配成功,因為IntentFilter不聲明的部分不進行比較。

換句話講,任何符合content://com.silenceburn.SdCardTester:1000/的事件,無論path是什麼,都可以匹配成功。

接下來是真正的data部分的,也就是URI的匹配規則如下:

1. 如果data的URI和datatype為空白,則 filter 的URI和type也必須為空白,才能匹配成功

2. 如果data的URI不為空白,但是datatype為空白,則 filter 必須定義URI並匹配成功,且type為空白,才能匹配成功

3. 如果data的URI為空白,但是datatype不為空白,則 filter 必須URI為空白,定義type並匹配成功,才能匹配成功

4. 如果data的URI和data都不為空白,則 filter 的URI和type都必須定義並匹配成功,才能匹配成功。對於URI部分,有一個特殊處理,就是即使IntentFilter沒有定義URI,content和file兩種URI也作為既存的URI存在。


除了明朝那些事兒,還有什朝什事兒?

流血的仕途
如果這是宋史
那是漢朝
原來這才是春秋
這幾本都不錯 ,你可以看看
 
那年那兔那些事兒吧裡氣氛是什情況?裡面都是些什樣的人說?算是愛國吧?

如果你在網上說:我愛黨愛國!那麼人們會罵你五毛
如果你在網上說:我不愛黨也不愛國!那麼人們會罵你JY美分
如果你在網上說:我愛黨但不愛國!人們會說你深井冰
如果你在網上說:我愛國但不愛黨!五毛會說你偽君子,JY美分們會說你不明智心存幻想,但是大多數人們會說你很正常!
所以網上會有很多人說:我愛國但不愛黨!
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.