Android入門之在Activity之間穿梭的Intent

概述

Intent 是 Android 程序中各組件之間進行交互的一種重要方式,它不僅可以指明當前組件想要執行的動作,還可以在不同組件之間傳遞數據

Intent 大致可分為兩種:顯式 Intent 和隱式 Intent

1. 顯式 Intent

Intent 有多個構造函數的重載,其中一個是 Intent(Context packetContext, Class<?> cls),這個構造函數接收兩個參數:

  • 第一個參數 Context 要求提供一個啟動 Activity 的上下文
  • 第二個參數 Class 用於指定想要啟動的目標 Activity

通過這個構造函數可以構建出 Intent,Activity 類中提供瞭一個 startActivity() 方法,專門啟動 Activity,它接收一個 Intent 參數。我們定義一個按鈕 button1,修改點擊事件

button1.setOnClickListener {
    val intent = Intent(this, SecondActivity::class.java)
    startActivityForResult(intent)
}

使用這種方式啟動 Activity,Intent 的意圖十分明顯,因此稱之為顯式 Intent

2. 隱式 Intent

隱式 Intent 並不明確指出想要啟動哪一個 Activity,而是指定瞭一系列更為抽象的 action 和 category 等信息,然後交由系統去分析這個 Intent,並幫助我們找出適合的 Activity 去啟動

通過在 <activity> 標簽配置 <intent-filter> 的內容,可以指定當前 Activity 能夠響應的 action 和 category,打開 AndroidManifest.xml,添加如下代碼:

<activity android:name=".SecondActivity">
	<intent-filter>
		<action android:name="com.example.activitytest.ACTION_START" />
		<category android:name="android.intent.category.DEFAULT" />
        <category android:name="com.example.activityest.MY_CATEGORY" />
	</intent-filter>
</activity>

我們指明瞭當前 Activity 可以響應 com.example.activitytest.ACTION_START 這個 action,而 <category> 標簽則包含瞭一些附加信息。隻有 <action> 和 <category> 中的內容同時匹配 Intent 中指定的 action 和 category 時,這個 Activity 才能響應該 Intent

button1.setOnClickListener {
    val intent = Intent("com.example.activitytest.ACTION_START")
    intent.addCategory("com.example.activityest.MY_CATEGORY")
    startActivity(intent)
}

使用隱式 Intent 不僅可以啟動自己程序內的 Activity,還可以啟動其他程序的 Activity,這使得多個應用程序之間的功能共享成為可能。比如你的應用程序需要展示一個網頁,隻需要調用系統的瀏覽器來打開這個網頁即可

button1.setOnClickListener {
	val intent = Intent(Intent.ACTION_VIEW)
	intent.data = Uri.parse("https://www.baidu.com")
	startActivity(intent)
}

使用 Intent 傳遞數據

1. 向下一個 Activity 傳遞數據

在啟動 Activity 時傳遞數據的思路很簡單,Intent 提供瞭一系列 putExtra() 方法的重載,可以把數據暫存在 Intent 中,在啟動另一個 Activity 時,再把數據從 Intent 中取出即可

button1.setOnClickListener {
    val data = "Hello SecondActivity"
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("extra_data", data)
    startActivity(intent)
}

然後在 SecondActivity 中將傳遞的數據取出

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.sceond_layout)
    val extraData = intent.getStringExtra("extra_data")
    Log.d("SecondActivity", "extra data is $extraData")
}

2. 返回數據給上一個 Activity

Activity 類中有一個啟動 Activity 的 startActivityForResult() 方法,可以在 Activity 銷毀時返回結果給上一個 Activity,該方法接收兩個參數:

  • 第一個參數還是 Intent
  • 第二個參數是請求碼,用於在之後的回調中判斷數據的來源

修改 FirstActivity 中按鈕的點擊事件代碼如下,這裡使用瞭 startActivityForResult() 方法來啟動 SecondActivity,請求碼隻要是個唯一值,這裡傳入 1

button1.setOnClickListener {
    val intent = Intent(this, SecondActivity::class.java)
    startActivityForResult(intent, 1)
}

接下來在 SecondActivity 中給按鈕註冊點擊事件,並在點擊事件中添加返回數據的邏輯

class SecondActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.sceond_layout)
        button2.setOnClickListener {
            val intent = Intent()
            intent.putExtra("data_return", "Hello FirstActivity")
            setResult(RESULT_OK, intent)
            finish()
        }
    }
}

這裡還是構建瞭一個 Intent,隻不過這個 Intent 僅僅用來傳遞數據,然後調用瞭 setResult() 方法,該方法專門向上一個 Activity 返回數據

setResult() 方法接收兩個參數:

  • 第一個參數用於向上一個 Activity 返回處理結果,一般隻使用 RESULT_OK 或 RESULT_CANCELED 這兩個值
  • 第二個參數則把帶有數據的 Intent 傳遞回去

由於我們使用 startActivityForResult() 方法來啟動 SecondActivity,SecondActivity 銷毀後會回調上一個 Activity 的 onActivityResult() 方法,因此需要在 FirstActivity 中重寫該方法來得到返回數據

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        1 -> if (resultCode == RESULT_OK) {
            val returnedData = data?.getStringExtra("data_return")
            Log.d("FirstActivity", "returned data is $returnedData")
        }
    }
}

onActivityResult() 方法帶有三個參數:

  • 第一個參數 requestCode,即我們啟動 Activity 時傳入的請求碼
  • 第二個參數 resultCode,即我們在返回數據時傳入的處理結果
  • 第三個參數 data,即攜帶返回數據的 Intent

由於在一個 Activity 中有可能調用 startActivityForResult() 來啟動很多不同的 Activity,而每一個 Activity 返回的數據都會回調到 onActivityResult() 方法,因此我們首先要做的是通過檢查 requestCode 的值判斷數據來源,再通過 resultCode 的值來判斷處理結果是否成功,最後從 data 中取值並打印

到此這篇關於Android入門之在Activity之間穿梭的Intent 的文章就介紹到這瞭,更多相關Android Intent內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: