人生巔峰的夢想之初!—Intent全解析

  • 2019 年 10 月 4 日
  • 筆記

前言

Hi,新的征程開始啦,關於各種控件我們給大家介紹的已經差不多了,各位花粉已經陪伴着我們走過了一個階段,本篇就是我們新征程的開始,當然,我們會在新征程之中偶爾穿插一些實戰控件的使用,讓大家學習的內容不再單一,還在等什麼,緊跟我們的步伐,為了白富…理想而出發!!

簡介

Intent作用

Intent 直譯為 "意圖",它用於在 Android 系統組件之間進行交互。它可被用來啟動 Activity、發生信息到 BroadCastReciver,啟動並與 service 進行交互。

Intent 分類

兩種形式的Intent
  • 顯示 Intent

顯示 Intent 通過它的 setCompoent()setClass() 來明確的指明要進行交互的組件,一般情況下不再會包含其他信息。

代碼示例:

 Intent intent = new Intent(MainActivity.this,SecondActivity.class);   startActivity(intent);
  • 隱式 Intent

使用隱式 Intent 並沒有明確的指定特定組件,而是指定足夠的信息讓 Android系統去決定哪一個組件是最符合 Intent 信息,從而揀選出最合適的組件。

隱式 Intent 一般在 Manifestfest.xml 給聲明組件通過設置 ActionDataCategory 給與組件足夠的信息,讓系統篩選出合適的組件。

下面是給要啟動的 ActivityAndroidManifest.xml文件中設置:

  <activity android:name=".SecondActivity">              <intent-filter>                  <action android:name="abcdefg" />                  <category android:name="android.intent.category.DEFAULT" />              </intent-filter>     </activity>

我們修改 SecondActivityAndroidManifest.xml 中聲明,在<intent-filter> 標籤中聲明 Intent 要過濾的信息。actionname 是一個字符串,可以自定義。

現在修改剛才在的 Activity 跳轉代碼如下:

  Intent intent = new Intent();    intent.setAction("abcdefg");//與 Manifest 中組件聲明的 action name 必須相同。    startActivity(intent);

運行程序,點擊跳轉按鈕仍然可以跳轉到 SecondActivity

IntentStructure

事實上可以把 Intent 當做一個工具,用於綁定不同組件(甚至是不相同的應用程序之間)。程序在運行時通過 Intent 來延遲運行時綁定。最重要的用途就是啟動 Activity,它可以被認為是 Activity 之間的粘合劑,而它本身是就是一個包含要執行動作的數據結構。

  • action :描述要被執行的動作。例如:Intent.ACTION_VIEW 用於顯示用戶的數據。比較通用,會根據用戶的數據類型打開相應的Activity。 Uri uri = Uri.parse("http://www.google.com"); Intent intent = new Intent(Intent.ACTION_VIEW,uri); startActivity(intent); //打開瀏覽器 –> 瀏覽網頁 Uri uri =Uri.parse("tel:1232333"); Intent intent = new Intent(Intent.ACTION_VIEW,uri); startActivity(intent); //打開撥號界面 –> 輸入1232333號碼 ….
  • category :給予額外的信息對於要執行的 action 。例如:
    • DEFAULT —— 默認動作
    • HOME —— 設置為本地桌面應用
    • LAUNCHER —— 應用的主 Activity
  • data :通常用來向 action 屬性提供操作數據。data 屬性默認接受一個 Uri 對象。
    • mimeType —— 用來設置該Data所指定的Uri對應的MIME類型,可自定義,只要符合abc/def格式即可。聲明該組件所能匹配的Intent的Type屬性。
    • scheme —— 用來聲明該組件所能匹配的Intent的Data屬性的scheme部分。
    • host —— 用來聲明該組件所能匹配的Intent的Data屬性的host部分。
    • port —— 用來聲明該組件所能匹配的Intent的Data屬性的port部分。
    • path —— 用來聲明該組件所能匹配的Intent的Data屬性的path部分。
    • pathPrefix —— 用來聲明該組件所能匹配的Intent的Data屬性的path前綴。
    • pathPattern —— 用來聲明該組件所能匹配的Intent的Data屬性的path字符串模版。

data子元素在配置的時候是可選的,但又是相互依存的,比如,如果沒有配置scheme,那麼其他所有的Uri屬性都被忽略;如果host沒有配置,那麼port以及path,pathPrefix,pathPattern都會被忽略(不起作用)。

Intent 傳遞數據

在使用 Intent 進行執行操作時,可以通過給 Intent 綁定數據到另一個組件中,從而實現數據的傳遞。在這個過程中存在數據從內存序列化或從文件序列化。

 Intent intent = new Intent(MainActivity.this,SecondActivity.class);   intent.putExtra("Name","Android"); //Name --> key , Android --> value   startActivity(intent);

數據的傳遞方式是以鍵值對的方式。

當跳轉到SecondActivity 再從 Intent 中通過 key(鍵)把攜帶的數據取出。

   TextView textView = findViewById(R.id.tv_content);            Intent intent = getIntent();//獲取傳遞數據的 Intent          String name = intent.getStringExtra("Name"); //通過 key 取出數據            if (!name.isEmpty()) {               //把界面上原來的字符串SecondActivity進行替換              textView.setText(name);          }

下面是通過源碼查看的Intent所支持的傳遞數據類型。

Intent 返回數據到上一個界面

當使用 IntentMainActivity 跳轉到 SecondActivity ,當在關閉或返回 MainActivity 時需要從 SecondActivity 攜帶數據到 MainActivity

這時,需要在啟動 Activity 的時候使用 startActivityForResult(Intent intent, int requestCode) 方式啟動。這個原理是當使用 startActivityForResult() 方式啟動 Activity 時在返回時系統會回調 ActivityonActivityResult(int requestCode, int resultCode, Intent data) 方法。

注意這裡有兩個特殊的參數:

  • requestCode —— 請求碼。使用請求碼可以判斷當多個Activity 啟動同一個 Activity 時,確定是哪一個 Activity 啟動的。
  • resultCode —— 響應碼。使用響應碼可以從上一個 Activity 中返回的多類型數據中,確定需要哪一種數據。

很明顯返回的數據是包含在 onActivityResult(int requestCode, int resultCode, Intent data) 回調方法的 Intent 當中。

MainActivity 中重寫回調方法獲取從SecondActivity 中設置的數據通過 key。然後將原來界面上的文字 MainActivity 設置為從 SecondActivity 中取回的值。

SecondActivity 中通過 setResult()方法設置數據,通過 Intent 對象。運行程序如下: