日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Intent Android 詳解

 wanwanstudy 2012-02-11

Intents and Intent Filters 三種應(yīng)用程序基本組件
activity, service和broadcast receiver——是使用稱為intent的消息來激活的。

 

Intent消息傳遞是一種組件間運(yùn)行時(shí)綁定的機(jī)制. intent是Intent對(duì)象, 它包含了需要做的操作的描述, 或者, 對(duì)于廣播來說, 包含了正在通知的消息內(nèi)容. 對(duì)于向這三種組件發(fā)送intent有不同的機(jī)制:
使用Context.startActivity() 或 Activity.startActivityForResult(), 傳入一個(gè)intent來啟動(dòng)一個(gè)activity.
使用 Activity.setResult(), 傳入一個(gè)intent來從activity中返回結(jié)果.
將intent對(duì)象傳給Context.startService()來啟動(dòng)一個(gè)service或者傳消息給一個(gè)運(yùn)行的service.
將intent對(duì)象傳給 Context.bindService()來綁定一個(gè)service.
將 intent對(duì)象傳給 Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等廣播方法,則它們被 傳給 broadcast receiver.

在上述三種情況下, android系統(tǒng)會(huì)自己找到合適的activity, service, 或者 broadcast receivers來響應(yīng)intent. 三者的intent相互獨(dú)立互不干擾. Intent Objects Intent對(duì)象 一個(gè)intent對(duì)象包含了接受該intent的組件的信息(例如需要的動(dòng)作和該動(dòng)作需要的數(shù)據(jù))和android系統(tǒng)所需要的信息(例如該組件的類別, 以及如何啟動(dòng)它). 具體的說: 組件名稱 為一個(gè)ComponentName 對(duì)象. 它是目標(biāo)組件的完整名(例如"com.example.project.app.FreneticActivity")和應(yīng)用程序manifest文件設(shè) 定的包名(例如"com.example.project")的組合.前者的包名部分和后者不一定一樣. 組件名稱是可選的. 如果設(shè)定了的話, Intent對(duì)象會(huì)被傳給指定的類的一個(gè)實(shí)例. 如果不設(shè)定, 則android使用其它信息來定位合適的目標(biāo). 組件名稱是使用setComponent(), setClass(),或 setClassName()來設(shè)定, 使用 getComponent()來獲取. Action 一個(gè)字符串, 為請(qǐng)求的動(dòng)作命名, 或者, 對(duì)于broadcast intent, 發(fā)生的并且正在被報(bào)告的動(dòng)作. 例如: 常量 目標(biāo)組件 動(dòng)作 ACTION_CALL activity 發(fā)起一個(gè)電話呼叫. ACTION_EDIT activity 顯示數(shù)據(jù)給用戶來編輯. ACTION_MAIN activity 將該activity作為一個(gè)task的第一個(gè)activity啟動(dòng),不傳入?yún)?shù)也不期望返回值. ACTION_SYNC activity 將設(shè)備上的數(shù)據(jù)和一個(gè)服務(wù)器同步. ACTION_BATTERY_LOW broadcast receiver 發(fā)出電量不足的警告. ACTION_HEADSET_PLUG broadcast receiver 一個(gè)耳機(jī)正被插入或者拔出. ACTION_SCREEN_ON broadcast receiver 屏幕被點(diǎn)亮. ACTION_TIMEZONE_CHANGED broadcast receiver 時(shí)區(qū)設(shè)置改變. 你也可以定義自己的action字符串用來啟動(dòng)你的應(yīng)用程序. 自定義的action應(yīng)該包含應(yīng)用程序的包名.例如"com.example.project.SHOW_COLOR". action很大程度上決定了intent的另外部分的結(jié)構(gòu), 就像一個(gè)方法名決定了它接受的參數(shù)和返回值一樣. 因此, 最好給action一個(gè)最能反映其作用的名字. 一個(gè)intent對(duì)象中的action是使用getAction()和setAction()來讀寫的. Data 需要操作的數(shù)據(jù)的URI和它的MIME(多用途互聯(lián)網(wǎng)郵件擴(kuò)展,Multipurpose Internet Mail Extensions)類型. 例如, 如果action為ACTION_EDIT, 那么Data將包含待編輯的數(shù)據(jù)URI. 如果action為ACTION_CALL, Data將為tel:電話號(hào)碼的URI. 如果action為ACTION_VIEW, 則Data為http:網(wǎng)絡(luò)地址的URI. 當(dāng)將一個(gè)intent和一個(gè)組件相匹配時(shí), 除了URI外數(shù)據(jù)類型也很重要. 例如, 一個(gè)顯示圖片的程序不應(yīng)該用來處理聲音文件. 數(shù)據(jù)類型常??梢詮腢RI推斷, 特別是content:URI, 它表示該數(shù)據(jù)屬于一個(gè)content provider. 但數(shù)據(jù)類型也可以被intent對(duì)象顯示聲明. setData()方法設(shè)置URI, 而setType()方法指定MIME類型, setDataAndType()設(shè)置數(shù)據(jù)URI和MIME類型. 它們可以使用getData()和getType()來讀取. Category 一個(gè)字符串,包含了關(guān)于處理該intent的組件的種類的信息. 一個(gè)intent對(duì)象可以有任意個(gè)category. intent類定義了許多category常數(shù), 例如: 常量 含義 CATEGORY_BROWSABLE 目標(biāo)activity可以使用瀏覽器來顯示-例如圖片或電子郵件消息. CATEGORY_GADGET 該activity可以被包含在另外一個(gè)裝載小工具的activity中. CATEGORY_HOME 該activity顯示主屏幕,也就是用戶按下Home鍵看到的界面. CATEGORY_LAUNCHER 該activity可以作為一個(gè)任務(wù)的第一個(gè)activity,并且列在應(yīng)用程序啟動(dòng)器中. CATEGORY_PREFERENCE 該activity是一個(gè)選項(xiàng)面板. addCategory()方法為一個(gè)intent對(duì)象增加一個(gè)category, removeCategory刪除一個(gè)category, getCategories()獲取intent所有的category. Extras 為鍵-值對(duì)形式的附加信息. 例如ACTION_TIMEZONE_CHANGED的intent有一個(gè)"time-zone"附加信息來指明新的時(shí)區(qū), 而ACTION_HEADSET_PLUG有一個(gè)"state"附加信息來指示耳機(jī)是被插入還是被拔出. intent對(duì)象有一系列put...()和set...()方法來設(shè)定和獲取附加信息. 這些方法和Bundle對(duì)象很像. 事實(shí)上附加信息可以使用putExtras()和getExtras()作為Bundle來讀和寫. Flags 各種標(biāo)志. 很多標(biāo)志指示android系統(tǒng)如何啟動(dòng)一個(gè)activity(例如該activity屬于哪個(gè)任務(wù))和啟動(dòng)后如何處理它(例如, 它是否屬于最近activity列表中). android系統(tǒng)和應(yīng)用程序使用intent對(duì)象來送出系統(tǒng)廣播和激活系統(tǒng)定義的組件. Intent Resolution Intent解析

intent有兩種: 顯式intent使用名字來指定目標(biāo)組件. 由于組件名稱一般不會(huì)被其它開發(fā)者所熟知, 這種intent一般用于應(yīng)用程序內(nèi)部消息-- 例如一個(gè)activity啟動(dòng)一個(gè)附屬的service或者另一個(gè)activity. 隱式intent不指定目標(biāo)的名稱. 一般用于啟動(dòng)其它應(yīng)用程序的組件. Android將顯式intent發(fā)送給指定的類. intent對(duì)象中名字唯一決定接受intent的對(duì)象.

對(duì)于隱式intent, android系統(tǒng)必須找到最合適的組件來處理它. 它比較intent的內(nèi)容和intent filter. intent filter是組件的一個(gè)相關(guān)結(jié)構(gòu), 表示其接受intent的能力. android系統(tǒng)根據(jù)intent filter打開可以接受intent的組件. 如果一個(gè)組件沒有intent filter, 那么它只能接受顯式intent. 如果有, 則能同時(shí)接受二者. 當(dāng)一個(gè)intent和intent filter比較時(shí), 只考慮三個(gè)屬性: action, data, category. extra和flag在intent解析中沒有用. Intent filters activity, service和broadcast receiver可以有多個(gè)intent filter來告知系統(tǒng)它們能接受什么樣的隱式intent. intent filter的名字很形象: 它過濾掉不想接受的intent, 留下想接受的intent.

顯式intent無視intent filter. 一個(gè)組件對(duì)能做的每件事有單獨(dú)的filter. 例如, 記事本程序的NoteEditor activity有兩個(gè)filter -- 一個(gè)啟動(dòng)并顯示一個(gè)特定的記錄給用戶查看或編輯, 另一個(gè)啟動(dòng)一個(gè)空的記錄給用戶編輯. Filters and security Filter和安全 一個(gè)intent filter不一定安全可靠. 一個(gè)應(yīng)用程序可以讓它的某個(gè)組件去接受隱式intent, 但是它沒法防止這個(gè)組件接受顯示intent. 其它的程序總是可以使用自定義的數(shù)據(jù)加上顯式的程序名稱來調(diào)用該組件. 一個(gè)intent filter是IntentFilter類的實(shí)例, 但是它一般不出現(xiàn)在代碼中,而是出現(xiàn)在android Manifest文件中, 以的形式. (有一個(gè)例外是broadcast receiver的intent filter是使用 Context.registerReceiver()來動(dòng)態(tài)設(shè)定的, 其intent filter也是在代碼中創(chuàng)建的.) 一個(gè)filter有action, data, category等字段. 一個(gè)隱式intent為了能被某個(gè)intent filter接受, 必須通過3個(gè)測(cè)試. 一個(gè)intent為了被某個(gè)組件接受, 則必須通過它所有的intent filter中的一個(gè). Action 測(cè)試 . . . 一 個(gè)intent對(duì)象只能指定一個(gè)action, 而一個(gè)intent filter可以指定多個(gè)action. action列表不能為空, 否則它將組織所有的intent. 一個(gè)intent對(duì)象的action必須和intent filter中的某一個(gè)action匹配, 才能通過. 如果intent filter的action列表為空, 則不通過. 如果intent對(duì)象不指定action, 并且intent filter的action列表不為空, 則通過. Category 測(cè)試 . . . 注 意前面說到的對(duì)于action和category的常數(shù)是在代碼中用的,而不是manifest文件中用的. 例如, CATEGORY_BROWSABLE常數(shù)對(duì)應(yīng)xml中的表示為"android.intent.category.BROWSABLE". 一個(gè)intent要通過category測(cè)試, 那么該intent對(duì)象中的每個(gè)category都必須和filter中的某一個(gè)匹配. 理論上來說, 一個(gè)intent對(duì)象如果沒有指定category的話, 它應(yīng)該能通過任意的category 測(cè)試. 有一個(gè)例外: android把所有的傳給startActivity()的隱式intent看做至少有一個(gè)category: "android.intent.category.DEFAULT". 因此, 想要接受隱式intent的activity必須在intent filter中加入"android.intent.category.DEFAULT". ("android.intent.action.MAIN" 和"android.intent.category.LAUNCHER"的intent filter例外. 它們不需要"android.intent.category.DEFAULT".) Data test . . . 每個(gè)元 素指定了一個(gè)URI和一個(gè)數(shù)據(jù)類型. URI每個(gè)部分為不同的屬性 -- scheme, host, port, path: scheme://host:port/path 例如, 在如下的URI中: content://com.example.project:200/folder/subfolder/etc scheme為"content", host為"com.example.project", port為"200", path為"folder/subfolder/etc". host和port一起組成了URI authority. 如果host未指定,則port被忽略. 這些屬性都是可選的,但它們并非相互獨(dú)立: 要使一個(gè)authority有意義,必須指定一個(gè)scheme. 要使一個(gè)path有意義, 必須指定一個(gè)scheme和一個(gè)authority. 當(dāng)intent對(duì)象中的URI和intent filter中相比較時(shí), 它只和filter中定義了的部分比較. 例如, 如果filter中之定義了scheme,那么所有包含該scheme的URI的intent對(duì)象都通過測(cè)試.對(duì)于path來說,可以使用通配符來進(jìn)行部 分匹配. 元素的type屬性指定了數(shù)據(jù)類型. 它在filter中比在URI中更常見. intent對(duì)象和filter都可以使用"*"通配符作為子類型. 例如"text/*" "audio/*"表示所有的子類型都匹配. data測(cè)試的規(guī)則如下: 一個(gè)不含uri也不含數(shù)據(jù)類型的intent對(duì)象只通過兩者都不包含的filter. 一個(gè)含uri但不含數(shù)據(jù)類型的intent對(duì)象(并且不能從uri推斷數(shù)據(jù)類型的)只能通過這樣的filter: uri匹配, 并且不指定類型. 這種情況限于類似mailto:和tel:這樣的不指定實(shí)際數(shù)據(jù)的uri. 一個(gè)只包含數(shù)據(jù)類型但不包含URI的intent只通過這樣的filter: 該filter只列出相同的數(shù)據(jù)類型, 并且不指定uri. 一個(gè)既包含uri又包含數(shù)據(jù)類型的intent對(duì)象只通過這樣的filter: intent對(duì)象的數(shù)據(jù)類型和filter中的一個(gè)類型匹配, intent對(duì)象的uri要么和filter的uri匹配, 要么intent對(duì)象的uri為content:或者file:, 并且filter不指定uri. 如果一個(gè)intent可以通過多于一個(gè)activity或者service的filter, 那么用戶可能會(huì)被詢問需要啟動(dòng)哪一個(gè). 如果一個(gè)都沒有的話, 那么會(huì)拋出異常. Common cases 常見情況 上述的最后一個(gè)規(guī)則(d)說明了組件通常可以從文件和content provider中獲取數(shù)據(jù). 因此, 它們的filter可以只列出數(shù)據(jù)類型不列scheme. 這是個(gè)特殊情況. 下列元素告訴android該組件可以從一個(gè)content provider取得圖像數(shù)據(jù)并顯示之: 由于大部分可用的數(shù)據(jù)由content provider提供, 指定數(shù)據(jù)類型但不指定uri的filter是最常見的情況. 另外一個(gè)常見的配置是filter具有一個(gè)scheme和一個(gè)數(shù)據(jù)類型. 例如, 下列元素告訴android該component可以從網(wǎng)絡(luò)獲取圖像數(shù)據(jù)并顯示之: 考 慮用戶點(diǎn)擊一個(gè)網(wǎng)頁時(shí)瀏覽器的動(dòng)作. 它首先試圖顯示這個(gè)數(shù)據(jù)(當(dāng)做一個(gè)html頁來處理). 如果無法顯示, 則創(chuàng)建一個(gè)隱式intent, 并啟動(dòng)一個(gè)可以處理它的activity. 如果沒有這樣的activity, 那么它請(qǐng)求下載管理器來下載該數(shù)據(jù). 然后它將數(shù)據(jù)置于一個(gè)content provider的控制之下, 這樣有很多activity(擁有只有數(shù)據(jù)類型的filter)可以處理這些數(shù)據(jù). 大部分應(yīng)用程序還有一種方法來單獨(dú)啟動(dòng), 不需要引用任何特定的數(shù)據(jù). 這些能啟動(dòng)應(yīng)用程序的activity具有action為"android.intent.action.MAIN" 的filter. 如果它們需要在應(yīng)用程序啟動(dòng)器中顯示, 它們必須指定"android.intent.category.LAUNCHER" 的category. Using intent matching 使用intent匹配 intent和intent filter相匹配, 不僅為了尋找并啟動(dòng)一個(gè)目標(biāo)組件, 也是為了尋找設(shè)備上組件的信息. 例如, android系統(tǒng)啟動(dòng)了應(yīng)用程序啟動(dòng)器, 該程序位于屏幕的頂層, 顯示了用戶可以啟動(dòng)的程序, 這是通過查找設(shè)備上所有的action為"android.intent.action.MAIN" ,category為"android.intent.category.LAUNCHER"的intent filter所在的activity實(shí)現(xiàn)的. 然后它顯示了這些activity的圖標(biāo)和標(biāo)題. 類似的, 它通過尋找 "android.intent.category.HOME"的filter來定位主屏幕程序. 應(yīng)用程序可以用相同的方式來使用intent匹配. PackageManager 有一組query...()方法來尋找接受某個(gè)特定intent的所有組件, 還有一系列resolve...()方法來決定響應(yīng)一個(gè)intent的最佳組件. 例如, queryIntentActivities()返回一個(gè)activity列表, 這些activity可以執(zhí)行傳入的intent. 類似的還有queryIntentServices()和queryIntentBroadcastReceivers(). Note Pad Example 例子:記事本 記事本示例程序讓用戶可以瀏覽一個(gè)筆記列表, 查看, 編輯, 刪除和增加筆記. 這一節(jié)關(guān)注該程序定義的intent filter. 在其manifest文件中, 記事本程序定義了三個(gè)activity, 每個(gè)有至少一個(gè)intent filter. 它還定義了一個(gè)content provider來管理筆記數(shù)據(jù). manifest 文件如下: 第一個(gè)activity, NoteList, 和其它activity不同, 因?yàn)樗僮饕粋€(gè)筆記的目錄(筆記列表), 而不是一個(gè)單獨(dú)的筆記. 它一般作為該程序的初始界面. 它可以做以下三件事: 該filter聲明了記事本應(yīng)用程序的主入口. 標(biāo)準(zhǔn)的MAIN action是一個(gè)不需要任何其它信息(例如數(shù)據(jù)等)的程序入口, LAUNCHER category表示該入口應(yīng)該在應(yīng)用程序啟動(dòng)器中列出. 該filter聲明了改activity可以對(duì)一個(gè)筆記目錄做的事情. 它允許用戶查看或編輯該目錄(使用VIEW和EDIT action), 或者選取特定的筆記(使用PICK action). 元 素的mimeType指定了這些action可以操作的數(shù)據(jù)類型. 它表明該activity可以從一個(gè)持有記事本數(shù)據(jù)的content provider(vnd.google.note)取得一個(gè)或多個(gè)數(shù)據(jù)項(xiàng)的Cursor(vnd.android.cursor.dir). 注意該filter提供了一個(gè)DEFAULT category. 這是因?yàn)?Context.startActivity() 和 Activity.startActivityForResult()方法將所有的intent都作為作為包含了DEFAULT category來處理, 只有兩個(gè)例外: 顯式指明目標(biāo)activity名稱的intent. 包含MAIN action 和LAUNCHER category的intent. 因此, 除了MAIN和LAUNCHER的filter之外, DEFAULT category是必須的. 這 個(gè)filter描述了該activity能夠在不需要知道目錄的情況下返回用戶選擇的一個(gè)筆記的能力. GET_CONTENT action和PICK action相類似. 在這兩者中, activity都返回用戶選擇的筆記的URI. (返回給調(diào)用startActivityForResult()來啟動(dòng)NoteList activity的activity.) 在這里, 調(diào)用者指定了用戶選擇的數(shù)據(jù)類型而不是數(shù)據(jù)的目錄. 這個(gè)數(shù)據(jù)類型, vnd.android.cursor.item/vnd.google.note, 表示了該activity可以返回的數(shù)據(jù)類型 -- 一個(gè)筆記的URI. 從返回的URI, 調(diào)用者可以從持有筆記數(shù)據(jù)的content provider(vnd.google.note)得到一個(gè)項(xiàng)目(vnd.android.cursor.item)的Cursor. 也就是說, 對(duì)于PICK來說, 數(shù)據(jù)類型表示activity可以給用戶顯式的數(shù)據(jù)類型.對(duì)于GET_CONTENT filter, 它表示activity可以返回給調(diào)用者的數(shù)據(jù)類型. 下列intent可以被NoteList activity接受: action: android.intent.action.MAIN 不指定任何數(shù)據(jù)直接啟動(dòng)activity. action: android.intent.action.MAIN category: android.intent.category.LAUNCHER 不指定任何數(shù)據(jù)直接啟動(dòng)activity. 這是程序啟動(dòng)器使用的intent. 所有使用該組合的filter的activity被加到啟動(dòng)器中. action: android.intent.action.VIEW data: content://com.google.provider.NotePad/notes 要求activity顯示一個(gè)筆記列表,這個(gè)列表位于content://com.google.provider.NotePad/notes. 用戶可以瀏覽這個(gè)列表并獲取列表項(xiàng)的信息. action: android.intent.action.PICK data: content://com.google.provider.NotePad/notes 請(qǐng)求activity顯示content://com.google.provider.NotePad/notes下的筆記列表. 用戶可以選取一個(gè)筆記, activity將返回筆記的URI給啟動(dòng)NoteList的activity. action: android.intent.action.GET_CONTENT data type: vnd.android.cursor.item/vnd.google.note 請(qǐng)求activity提供記事本數(shù)據(jù)的一項(xiàng). 第二個(gè)activity, NoteEditor, 為用戶顯示一個(gè)筆記并允許他們編輯它. 它可以做以下兩件事: 這 個(gè)activity的主要目的是使用戶編輯一個(gè)筆記--VIEW或者EDIT一個(gè)筆記. (在category中,EDIT_NOTE是EDIT的同義詞.) intent包含匹配MIME類型vnd.android.cursor.item/vnd.google.note的URI--也就是某一個(gè)特定的筆記 的URI. 它一般來說是NoteList activity中的PICK或者GET_CONTENT action返回的. 像以前一樣,該filter列出了DEFAULT category. 該 activity的第二個(gè)目的是使用戶能夠創(chuàng)建一個(gè)新的筆記, 并插入到已存在的筆記目錄中. 該intent包含了匹配vnd.android.cursor.dir/vnd.google.note的URI, 也就是筆 有了這些能力, NoteEditor就可以接受以下intent: action: android.intent.action.VIEW data: content://com.google.provider.NotePad/notes/ID 要求activity顯示給定ID的筆記. action: android.intent.action.EDIT data: content://com.google.provider.NotePad/notes/ID 要求activity顯示指定ID的筆記,然后讓用戶來編輯它. 如果用戶保存了更改,則activity更新該content provider的數(shù)據(jù). action: android.intent.action.INSERT data: content://com.google.provider.NotePad/notes 要求activity創(chuàng)建一個(gè)新的空筆記在content://com.google.provider.NotePad/notes, 并允許用戶編輯它, 如果用戶保存了更改,則該URI被返回給調(diào)用者. 最后一個(gè)activity, TitleEditor, 允許用戶編輯筆記的標(biāo)題. 這可以通過直接調(diào)用activity(在intent中設(shè)置組件名稱)的方式來實(shí)現(xiàn). 但是這里我們用這個(gè)機(jī)會(huì)來展示如何在已有數(shù)據(jù)上進(jìn)行另外的操作(類似于windows中的打開方式->程序列表 -- 譯者注): 它 必須在一個(gè)特定的筆記上調(diào)用(data type vnd.android.cursor.item/vnd.google.note), 就像之前的VIEW和EDIT action一樣. 然而, 這里activity顯示筆記數(shù)據(jù)中包含的標(biāo)題, 而不是內(nèi)容. 除了支持DEFAULT category之外,title編輯器還支持了另外兩個(gè)category: ALTERNATIVE 和SELECTED_ALTERNATIVE. 這些category標(biāo)志著activity可以在選項(xiàng)菜單中呈現(xiàn)給用戶(就像LAUNCHER category表示activity可以在程序啟動(dòng)器中一樣). 注意filter還提供了一個(gè)顯示標(biāo)簽(android:label="@string/resolve_title")來更好的控制用戶在選項(xiàng)菜單中看 到的內(nèi)容. 有了這些能力, 以下的intent就可以被TitleEditor接受: action: com.android.notepad.action.EDIT_TITLE data: content://com.google.provider.NotePad/notes/ID 要求activity顯示給定筆記ID的標(biāo)題, 并允許用戶編輯該標(biāo)題.

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約