Intent Android 詳解

來源:互聯網
上載者:User

Intents and Intent Filters 三種應用程式基底本組件
activity, service和broadcast receiver——是使用稱為intent的訊息來啟用的。

 

Intent訊息傳遞是一種組件間運行時綁定的機制. intent是Intent對象, 它包含了需要做的操作的描述, 或者, 對於廣播來說, 包含了正在通知的訊息內容. 對於向這三種組件發送intent有不同的機制:
使用Context.startActivity() 或 Activity.startActivityForResult(), 傳入一個intent來啟動一個activity.
使用 Activity.setResult(), 傳入一個intent來從activity中返回結果.
將intent對象傳給Context.startService()來啟動一個service或者傳訊息給一個啟動並執行service.
將intent對象傳給 Context.bindService()來綁定一個service.
將intent對象傳給 Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等廣播方法,則它們被傳給 broadcast receiver.

在上述三種情況下, android系統會自己找到合適的activity, service, 或者 broadcast receivers來響應intent. 三者的intent相互獨立互不干擾. Intent Objects Intent對象 一個intent對象包含了接受該intent的組件的資訊(例如需要的動作和該動作需要的資料)和android系統所需要的資訊(例如該組件的類別,以及如何啟動它). 具體的說: 組件名稱 為一個ComponentName 對象. 它是目標組件的完整名(例如"com.example.project.app.FreneticActivity")和應用程式manifest檔案設定的包名(例如"com.example.project")的組合.前者的包名部分和後者不一定一樣. 組件名稱是可選的. 如果設定了的話, Intent對象會被傳給指定的類的一個執行個體. 如果不設定, 則android使用其它資訊來定位合適的目標. 組件名稱是使用setComponent(), setClass(),或 setClassName()來設定, 使用 getComponent()來擷取. Action 一個字串, 為請求的動作命名, 或者, 對於broadcast intent, 發生的並且正在被報告的動作. 例如: 常量 目標組件 動作 ACTION_CALL activity 發起一個撥打電話. ACTION_EDIT activity 顯示資料給使用者來編輯. ACTION_MAIN activity 將該activity作為一個task的第一個activity啟動,不傳入參數也不期望傳回值. ACTION_SYNC activity 將裝置上的資料和一個伺服器同步. ACTION_BATTERY_LOW broadcast receiver 發出電量不足的警告. ACTION_HEADSET_PLUG broadcast receiver 一個耳機正被插入或者拔出. ACTION_SCREEN_ON broadcast receiver 螢幕被點亮. ACTION_TIMEZONE_CHANGED broadcast receiver 時區設定改變. 你也可以定義自己的action字串用來啟動你的應用程式. 自訂的action應該包含應用程式的包名.例如"com.example.project.SHOW_COLOR". action很大程度上決定了intent的另外部分的結構, 就像一個方法名決定了它接受的參數和傳回值一樣. 因此, 最好給action一個最能反映其作用的名字. 一個intent對象中的action是使用getAction()和setAction()來讀寫的. Data 需要操作的資料的URI和它的MIME(多用途互連網郵件擴充,Multipurpose Internet Mail Extensions)類型. 例如, 如果action為ACTION_EDIT, 那麼Data將包含待編輯的資料URI. 如果action為ACTION_CALL, Data將為tel:電話號碼的URI. 如果action為ACTION_VIEW, 則Data為http:網路地址的URI. 當將一個intent和一個組件相匹配時, 除了URI外資料類型也很重要. 例如, 一個顯示圖片的程式不應該用來處理音效檔. 資料類型常常可以從URI推斷, 特別是content:URI, 它表示該資料屬於一個content provider. 但資料類型也可以被intent對象顯示聲明. setData()方法設定URI, 而setType()方法指定MIME類型, setDataAndType()設定資料URI和MIME類型. 它們可以使用getData()和getType()來讀取. Category 一個字串,包含了關於處理該intent的組件的種類的資訊. 一個intent對象可以有任意個category. intent類定義了許多category常數, 例如: 常量 含義 CATEGORY_BROWSABLE 目標activity可以使用瀏覽器來顯示-例片或電子郵件訊息. CATEGORY_GADGET 該activity可以被包含在另外一個裝載小工具的activity中. CATEGORY_HOME 該activity顯示主畫面,也就是使用者按下Home鍵看到的介面. CATEGORY_LAUNCHER 該activity可以作為一個任務的第一個activity,並且列在應用程式啟動器中. CATEGORY_PREFERENCE 該activity是一個選項面板. addCategory()方法為一個intent對象增加一個category, removeCategory刪除一個category, getCategories()擷取intent所有的category. Extras 為鍵-值對形式的附加資訊. 例如ACTION_TIMEZONE_CHANGED的intent有一個"time-zone"附加資訊來指明新的時區, 而ACTION_HEADSET_PLUG有一個"state"附加資訊來指示耳機是被插入還是被拔出. intent對象有一系列put...()和set...()方法來設定和擷取附加資訊. 這些方法和Bundle對象很像. 事實上附加資訊可以使用putExtras()和getExtras()作為Bundle來讀和寫. Flags 各種標誌. 很多標誌指示android系統如何啟動一個activity(例如該activity屬於哪個任務)和啟動後如何處理它(例如, 它是否屬於最近activity列表中). android系統和應用程式使用intent對象來送出系統廣播和啟用系統定義的組件. Intent Resolution Intent解析

intent有兩種: 顯式intent使用名字來指定目標組件. 由於組件名稱一般不會被其它開發人員所熟知, 這種intent一般用於應用程式內部訊息-- 例如一個activity啟動一個附屬的service或者另一個activity. 隱式intent不指定目標的名稱. 一般用於啟動其它應用程式的組件. Android將顯式intent發送給指定的類. intent對象中名字唯一決定接受intent的對象.

對於隱式intent, android系統必須找到最合適的組件來處理它. 它比較intent的內容和intent filter. intent filter是組件的一個相關結構, 表示其接受intent的能力. android系統根據intent filter開啟可以接受intent的組件. 如果一個組件沒有intent filter, 那麼它只能接受顯式intent. 如果有, 則能同時接受二者. 當一個intent和intent filter比較時, 只考慮三個屬性: action, data, category. extra和flag在intent解析中沒有用. Intent filters activity, service和broadcast receiver可以有多個intent filter來告知系統它們能接受什麼樣的隱式intent. intent filter的名字很形象: 它過濾掉不想接受的intent, 留下想接受的intent.

顯式intent無視intent filter. 一個組件對能做的每件事有單獨的filter. 例如, 記事本程式的NoteEditor activity有兩個filter -- 一個啟動並顯示一個特定的記錄給使用者查看或編輯, 另一個啟動一個空的記錄給使用者編輯. Filters and security Filter和安全 一個intent filter不一定安全可靠. 一個應用程式可以讓它的某個組件去接受隱式intent, 但是它沒法防止這個組件接受顯示intent. 其它的程式總是可以使用自訂的資料加上顯式的程式名稱來調用該組件. 一個intent filter是IntentFilter類的執行個體, 但是它一般不出現在代碼中,而是出現在android Manifest檔案中, 以的形式. (有一個例外是broadcast receiver的intent filter是使用 Context.registerReceiver()來動態設定的, 其intent filter也是在代碼中建立的.) 一個filter有action, data, category等欄位. 一個隱式intent為了能被某個intent filter接受, 必須通過3個測試. 一個intent為了被某個組件接受, 則必須通過它所有的intent filter中的一個. Action 測試 . . . 一個intent對象只能指定一個action, 而一個intent filter可以指定多個action. action列表不可為空, 否則它將組織所有的intent. 一個intent對象的action必須和intent filter中的某一個action匹配, 才能通過. 如果intent filter的action列表為空白, 則不通過. 如果intent對象不指定action, 並且intent filter的action列表不為空白, 則通過. Category 測試 注意前面說到的對於action和category的常數是在代碼中用的,而不是manifest檔案中用的. 例如, CATEGORY_BROWSABLE常數對應xml中的表示為"android.intent.category.BROWSABLE". 一個intent要通過category測試, 那麼該intent對象中的每個category都必須和filter中的某一個匹配. 理論上來說, 一個intent對象如果沒有指定category的話, 它應該能通過任意的category 測試. 有一個例外: android把所有的傳給startActivity()的隱式intent看做至少有一個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 . . . 每個元素指定了一個URI和一個資料類型. URI每個部分為不同的屬性 -- 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被忽略. 這些屬性都是可選的,但它們並非相互獨立: 要使一個authority有意義,必須指定一個scheme. 要使一個path有意義, 必須指定一個scheme和一個authority. 當intent對象中的URI和intent filter中相比較時, 它只和filter中定義了的部分比較. 例如, 如果filter中之定義了scheme,那麼所有包含該scheme的URI的intent對象都通過測試.對於path來說,可以使用萬用字元來進行部分匹配. 元素的type屬性指定了資料類型. 它在filter中比在URI中更常見. intent對象和filter都可以使用"*"萬用字元作為子類型. 例如"text/*" "audio/*"表示所有的子類型都匹配. data測試的規則如下: 一個不含uri也不含資料類型的intent對象只通過兩者都不包含的filter. 一個含uri但不含資料類型的intent對象(並且不能從uri推斷資料類型的)只能通過這樣的filter: uri匹配, 並且不指定類型. 這種情況限於類似mailto:和tel:這樣的不指定實際資料的uri. 一個只包含資料類型但不包含URI的intent只通過這樣的filter: 該filter只列出相同的資料類型, 並且不指定uri. 一個既包含uri又包含資料類型的intent對象只通過這樣的filter: intent對象的資料類型和filter中的一個類型匹配, intent對象的uri要麼和filter的uri匹配, 要麼intent對象的uri為content:或者file:, 並且filter不指定uri. 如果一個intent可以通過多於一個activity或者service的filter, 那麼使用者可能會被詢問需要啟動哪一個. 如果一個都沒有的話, 那麼會拋出異常. Common cases 常見情況 上述的最後一個規則(d)說明了組件通常可以從檔案和content provider中擷取資料. 因此, 它們的filter可以只列出資料類型不列scheme. 這是個特殊情況. 下列元素告訴android該組件可以從一個content provider取得映像資料並顯示之: 由於大部分可用的資料由content provider提供, 指定資料類型但不指定uri的filter是最常見的情況. 另外一個常見的配置是filter具有一個scheme和一個資料類型. 例如, 下列元素告訴android該component可以從網路擷取映像資料並顯示之: 考慮使用者點擊一個網頁時瀏覽器的動作. 它首先試圖顯示這個資料(當做一個html頁來處理). 如果無法顯示, 則建立一個隱式intent, 並啟動一個可以處理它的activity. 如果沒有這樣的activity, 那麼它請求下載管理員來下載該資料. 然後它將資料置於一個content provider的控制之下, 這樣有很多activity(擁有只有資料類型的filter)可以處理這些資料. 大部分應用程式還有一種方法來單獨啟動, 不需要引用任何特定的資料. 這些能啟動應用程式的activity具有action為"android.intent.action.MAIN" 的filter. 如果它們需要在應用程式啟動器中顯示, 它們必須指定"android.intent.category.LAUNCHER" 的category. 第一個activity, NoteList, 和其它activity不同, 因為它操作一個筆記的目錄(筆記列表), 而不是一個單獨的筆記. 它一般作為該程式的初始介面. 它可以做以下三件事:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.