天天看點

Android界月老Intent詳解

1.什麼是Intent?

  • Intent中文意思是 “意圖、目标”,它是Android為應用間和應用内提供的互動與通訊的“信使”,你也可以稱它為Android界月老。
  • Intent是一種運作時綁定(runtime binding)機制,在程式運作的過程中,它可以連接配接多個不同的元件。通過Intent,你的程式可以向Android表達某種意圖,Android會根據請求的内容篩選出符合要求的元件來響應。

2.Intent的使用場景:

   a.在Activity之間:

  • 使用startActivity(),傳入一個intent來啟動一個activity。
Android界月老Intent詳解
  • startActivityForResult()是用于回傳資料的,第一個參數是 intent,第二個參數是請求碼(請求碼用于之後在onActivityResult回調中判斷資料的來源),我們在SecondActivity中通過 setResult()向MainActivity傳回資料,第一個參數是向上一個活動(MainActivity)傳回的處理結果,一般使用RESULT_OK或RESULT_CANCELED,第二個參數是攜帶了要傳輸的資料的intent。
Android界月老Intent詳解

然後在MainActivity中重寫onActivityResult方法拿到回傳過來的資料,其中requestCode表示請求碼,resultCode表示請求結果碼,data就是你剛才在SecondActivity中通過setResult方法設定的intent,資料就在其中。

Android界月老Intent詳解

b.在廣播中的使用:

  • 建立intent對象,設定廣播的action,設定元件,最後通過sendBroadcast()發送一個普通廣播。P個S:sendBroadcast實際調用的是ContextImpl的sendBroadcast。ContextImpl這個檔案是保護檔案,就是注解了是内部保護檔案,是以在eclipse,Androidstudio中都是不顯示的。是以可以去SDk的安裝目錄中的sources檔案夾中直接找那個Java檔案,/android-sdk/sources/android-28/android/app/ContextImpl.java。
Android界月老Intent詳解
  • 容我再P個S:我的手機是9.0系統,剛開始寫上面的demo時,沒有加setComponent這一行,怎麼整都接受不到廣播,後來檢視谷歌官網對于8.0的變更有這麼一條:
Android界月老Intent詳解
  • 也就是說,我們也可以通過對廣播接受器進行動态注冊解決這個問題。貌似扯遠了。。。

c.在service中的使用:

Android界月老Intent詳解

3.Intent的屬性:

  • component(元件):要跳轉到的目标元件
  • action(動作):用來指定意圖的行為
  • category(類别):用來指定動作的類别
  • data(資料):表示與動作要操縱的資料
  • type(資料類型):對于data範例的描寫
  • extras(擴充資訊):擴充資訊
  • Flags(标志位):期望這個意圖的運作模式

下面逐個學習這些屬性:

a.component(元件)

在介紹Component之前,我們首先來了解ComponentName這個類;ComponentName與Intent同位于android.content包下,這個類主要用來定義可見一個應用程式元件,通過檢視源碼,我們了解到他有五個構造方法:

Android界月老Intent詳解

案例:建立兩個應用:TaobaoApp、BaiduApp,在“淘寶”界面拉起“百度”界面:

在TaobaoApp主界面中,我們通過ComponentName(String pkg,String cls)構造方法(第一個參數是目标元件的包名,第二個參數是目标元件具體的類名:)執行個體化ComponentName對象,并将它傳入intent:

Android界月老Intent詳解

在BaiduApp主界面隻做簡單的展示:

Android界月老Intent詳解

b.action(動作)

此标簽用于指定目前元件可以執行哪些操作,可以指定多個action,比如目前元件啟動的intent指定的action與其他元件在<intent-filter>所列出的任意一個比對的話,目前元件就可以完成這個action:

常用的Action如下所示:

  • ACTION_CALL activity 啟動一個電話.  
  • ACTION_EDIT activity 顯示使用者編輯的資料.  
  • ACTION_MAIN 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 改變時區警告. 

兩條原則:

(1)一條<intent-filter>元素至少應該包含一個<action>,否則任何Intent請求都不能和該<intent-filter>比對。

(2)如果Intent請求的action和<intent-filter>中個任意一條<action>比對,那麼該Intent就可以啟動該activity(前提是除了action的其它項也要比對通過)。

兩條注意:

如果Intent請求或<intent-filter>中沒有說明具體的action類型,那麼會出現下面兩種情況:

(1)如果<intent-filter>中沒有包含任何action類型,那麼無論什麼Intent請求都無法和這條<intent-filter>比對。

(2)如果Intent請求中沒有設定action類型,那麼隻要<intent-filter>中包含有action類型,這個Intent請求就将順利地通過<intent-filter>的行為測試。

c.category(類别)

Category用來指定目前動作(action)被執行的環境,也就是說元件在哪種環境中才能被激活。

常用的Category屬性如下所示:

  • CATEGORY_DEFAULT:Android系統中預設的執行方式,按照普通Activity的執行方式執行。表示所有intent都可以激活它   
  • CATEGORY_HOME:設定該元件為Home Activity 
  • CATEGORY_PREFERENCE:設定該元件為Preference   
  • CATEGORY_LAUNCHER:設定該元件為在目前應用程式啟動器中優先級最高的Activity,通常與入口ACTION_MAIN屬性配合使用
  • CATEGORY_BROWSABLE:設定該元件可以使用浏覽器啟動,表示該activity隻能用來浏覽網頁。   
  • CATEGORY_GADGET:設定該元件可以内嵌到另外的Activity中

注意:如果該元件想要通過隐式intent方式激活,那麼不能沒有任何category設定,至少包含一個android.intent.category.DEFAULT

d.data(資料)

我們先來看一個示例:

case R.id.btn_start_baidu://啟動TargetActivity
                Intent intentBaidu = new Intent(Intent.ACTION_VIEW);
                intentBaidu.setData(Uri.parse("http://www.baidu.com"));
                startActivity(intentBaidu);
                break;           

首先我們指定intent的action為Intent.ACTION_VIEW,再把百度的網址傳進Uri.parse方法中,最終解析成一個Uri對象,再調用intent.setData()方法把Uri對象傳進去,最後調用startActivity()就可以通路到百度了。

3.顯示和隐式Intent

intent.setAction("com.android.basic.summary.SecondActivity_ACTION_START");           
<activity android:name=".SecondAactivity">
            <intent-filter>
                <action android:name="com.android.basic.summary.SecondActivity_ACTION_START" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>           

持續更新。。。