Intent是什么?


一、理解Intent:

  在一個Android應用中,主要是由四種組件組成的,這四種組件可參考“Android應用的構成”。而這四種組件是獨立的,它們之間可以互相調用,協調工作,最終組成一個真正的Android應用。

  在這些組件之間的通訊中,主要是由Intent協助完成的。Intent 負責對應用中一次操作的動作動作涉及數據、附加數據進行描述,Android則根據此Intent的描述,負責找到對應的組件,將Intent傳遞給調用的組件,並完成組件的調用。  因此,Intent在這里起着一個媒體中介的作用,專門提供組件互相調用的相關信息,實現調用者與被調用者之間的解耦。

  例如,在一個聯系人維護的應用中,當我們在一個聯系人列表屏幕(假設對應的Activity為listActivity)上,點擊某個聯系人后,希望能夠跳出此聯系人的詳細信息屏幕(假設對應的Activity為detailActivity)為了實現這個目的,listActivity需要構造一個 Intent,這個Intent用於告訴系統,我們要做“查看”動作,此動作對應的查看對象是“某聯系人”,然后調用startActivity (Intent intent),將構造的Intent傳入,系統會根據此Intent中的描述,到ManiFest中找到滿足此Intent要求的Activity,系統會調用找到的 Activity,即為detailActivity,最終傳入Intent,detailActivity則會根據此Intent中的描述,執行相應的操作。

  Intent分為兩大類:顯性的(Explicit )、隱性的(Implicit)

顯性的Intent—>>在兩個Activity之間跳轉時如果使用intent的setClass來設置 Intent的發起方與接收方,或者直接new對象的時候構造發起方與接收方

     隱性的Intent—>>則不需要用setClass或setComponent來指定事件處理器,利用AndroidMenifest.xml中的配置就可以由平台定位事件的消費者
示例代碼:
  1. 顯式:

1 //方式一:
2 Intent intent = new Intent(Test.this, TestB.class);
3 startActivity(intent);
4 //方式二:
5 Intent intent = new Intent();
6 intent.setClass(TestBundle.this, Target.class);
7 intent.putExtras(mBundle); //傳遞信息
8 startActivity(intent);

    2. 隱式

//瀏覽網頁 (系統預定義配置)
Uri uri = Uri.parse("http://www.google.com");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);

二、 Intent的構成

要在不同的activity之間傳遞數據,就要在intent中包含相應的東西,一般來說數據中最基本的應該包括
【Action】

用來指明要實施的動作是什么,比如說ACTION_VIEW, ACTION_DIAL等;

具體的可以查閱android SDK-> reference中的Android.content.intent,里面的constants中定義了所有的action。

【Data】

要事實的具體的數據,一般由一個Uri變量來表示;

下面是一些簡單的例子:

ACTION_VIEW content://contacts/1 //顯示identifier為1的聯系人的信息
ACTION_DIAL   content://contacts/1 //給這個聯系人打電話

除了Action和data這兩個最基本的元素外,intent還包括一些其他的元素:
【 Category(類別)】

這個選項指定了將要執行的這個action的其他一些額外的信息;

例如:

  LAUNCHER_CATEGORY  表示Intent 的接受者應該在Launcher中作為頂級應用出現;

  ALTERNATIVE_CATEGORY  表示當前的Intent是一系列的可選動作中的一個,這些動作可以在同一塊數據上執行;

具體同樣可以參考android SDK-> reference中的Android.content.intent類。

【Type(數據類型)】

  顯式指定Intent的數據類型(MIME);

  一般Intent的數據類型能夠根據數據本身進行判定,但是通過設置這個屬性,可以強制采用顯式指定的類型而不再進行推導。

【component(組件)】

指定Intent的的目標組件的 類名稱;

通常 Android會根據Intent 中包含的其它屬性的信息,比如action、data/type、category進行查找,最終找到一個與之匹配的目標組件。但是,如果 component這個屬性有指定的話,將直接使用它指定的組件,而不再執行上述查找過程。指定了這個屬性以后,Intent的其它所有屬性都是可選的。

【extras(附加信息)】

是其它所有附加信息的集合;

使用extras可以為組件提供擴展信息,比如,如果要執行“發送電子郵件”這個動作,可以將電子郵件的標題、正文等保存在extras里,傳給電子郵件發送組件。

下面是這些額外屬性的幾個例子:
  //用來 Launch home screen. 

    ACTION_MAIN with category CATEGORY_HOME 

   //用來列出列表中的所有人的電話號碼

    ACTION_GET_CONTENT with MIME type vnd.android.cursor.item/phone
綜上可以看出,action、 data/type、category和extras 一起形成了一種語言,這種語言可以是android可以表達出諸如“給張三打電話”之類的短語組合。

三、 intent的解析

  應用程序的組件為了告訴Android自己能響應、處理哪些隱式Intent請求,可以聲明一個甚至多個Intent Filter。每個Intent Filter描述該組件所能響應Intent請求的能力——組件希望接收什么類型的請求行為,什么類型的請求數據。

  例如,網頁瀏覽器程序的Intent Filter就應該聲明它所希望接收的Intent Action是WEB_SEARCH_ACTION,以及與之相關的請求數據是網頁地址URI格式。

  怎樣為組件聲明自己的Intent Filter?  

    —>>>>常見的方法是在AndroidManifest.xml文件中用屬性< Intent-Filter>描述組件的Intent Filter。

  前面我們提到,隱式Intent(Explicit Intents)和Intent Filter(Implicit Intents)進行比較時的三要素是Intent的動作數據以及類別。實際上,一個隱式Intent請求要能夠傳遞給目標組件,必要通過這三個方面的檢查。如果任何一方面不匹配,Android都不會將該隱式Intent傳遞給目標組件。接下來我們講解這三方面檢查的具體規則。
  1.動作測試
    Java代碼

/*
    < intent-filter>元素中可以包括子元素< action>
    比如:
*/
<intent-filter ...>
  <action android:name=”com.example.project.SHOW_CURRENT” />
  <action android:name=”com.example.project.SHOW_RECENT” />
  <action android:name=”com.example.project.SHOW_PENDING” />
</intent-filter>

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

     如果Intent請求的Action和< intent-filter>中個某一條< action>匹配,那么該Intent就通過了這條< intent-filter>的動作測試。

     如果Intent請求或< intent-filter>中沒有說明具體的Action類型,那么會出現下面兩種情況。
        (1) 如果< intent-filter>中沒有包含任何Action類型,那么無論什么Intent請求都無法和這條< intent- filter>匹配;

        (2)反之,如果Intent請求中沒有設定Action類型,那么只要< intent-filter>中包含有Action類型,

         這個 Intent請求就將順利地通過< intent-filter>的行為測試。

  2.類別測試
    Java代碼

/* 
   < intent-filter>元素可以包含< category>子元素
    比如:
*/
    <intent-filter ...>
      <category android:name=”android.Intent.Category.DEFAULT” />
      <category android:name=”android.Intent.Category.BROWSABLE” />
    </intent-filter>

  只有當Intent請求中所有的Category與組件中某一個IntentFilter的< category>完全匹配時,才會讓該 Intent請求通過測試,IntentFilter中多余的< category>聲明並不會導致匹配失敗。一個沒有指定任何類別測試的 Intent-filter僅僅只會匹配沒有設置類別的Intent請求。
  3.數據測試
    Java代碼

<intent-filter ... >
    <data android:type=”video/mpeg” 
      android:scheme=”http”
      android:host="www.google.com" ... /> </intent-filter>

   元素指定了希望接受的Intent請求的數據URI和數據類型,URI被分成三部分來進行匹配:scheme、 authority和path。其中,用setData()設定的Inteat請求的URI數據類型必須與IntentFilter中scheme所指定的一致。若Intent-filter中還指定了authority或path,它們也需要相匹配才會通過測試。
  4.簡單例子說明
    講解完Intent基本概念之后,接下來我們就使用Intent激活Android自帶的電話撥號程序,通過這個實例你會發現,使用Intent並不像其概念描述得那樣難。

      最終創建Intent的代碼如下所示:
        Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse(”tel:13800138000″));
        創建好Intent之后,你就可以通過它告訴Android希望啟動新的Activity了。
        startActivity(intent);

四、Intent的構造函數

公共構造函數:
1、Intent()   空構造函數
2、Intent(Intent o)   拷貝構造函數
3、Intent(String action)   指定action類型的構造函數
4Intent(String action, Uri uri)   指定Action類型和Uri的構造函數,URI主要是結合程序之間的數據共享ContentProvider
5、Intent(Context packageContext, Class cls)   傳入組件的構造函數,也就是上文提到的
6、Intent(String action, Uri uri, Context packageContext, Class cls)   前兩種結合體
Intent有六種構造函數,3、4、5是最常用的,並不是其他沒用!
Intent(String action, Uri uri) 的action就是對應在AndroidMainfest.xml中的action節點的name屬性值。在Intent類中定義了很多的Action和Category常量。
  示例代碼:

  Intent intent = new Intent(Intent.ACTION_EDIT, null);

  startActivity(intent);

    示例代碼二是用了第四種構造函數,只是uri參數為null。執行此代碼的時候,系統就會在程序主配置文件AndroidMainfest.xml中尋找
  對應的Activity,如果對應為多個activity具有此時就會彈出一個dailog選擇Activity,如下圖:
  如果是用示例代碼一那種方式進行發送則不會有這種情況。

五、利用Intent在Activity之間傳遞數據

在Main中主要代碼:

1 Bundle bundle = new Bundle();
2 bundle.putStringArray("NAMEARR", nameArr);
3 Intent intent = new Intent(Main.this, CountList.class);
4 intent.putExtras(bundle);
5 startActivity(intent);

在CountList中執行代碼:

Bundle bundle = this.getIntent().getExtras();
String[] arrName = bundle.getStringArray("NAMEARR");

  以上代碼就實現了Activity之間的數據傳遞~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM