做者 / Yacine Rezguiandroid
不管您是在應用中請求某項權限,從文件管理系統中選擇某個文件,仍是指望從第三方應用中獲取到某些數據,都會涉及到在 Activity 之間傳遞數據,而這也正是 Android 中進程間通訊的核心要點。近期咱們發佈了新的 ActivityResult API 來幫助簡化 Activity 間的數據通訊。安全
以前,想要從啓動的 Activity 中獲取到返回結果,應用須要在 Activity 和 Fragment 中實現 onActivityResult() 方法,而後檢查回調關聯到哪個 requestCode,並驗證該 requestCode 的結果是否爲 OK,最終再去驗證返回數據或擴展數據。maven
可是這樣的處理方式會讓咱們的代碼變得很是複雜,而且也沒法保證在 Activity 發送或接收數據時參數的類型安全。ide
ActivityResult API 被加入到 Jetpack 的 Activity 和 Fragment 庫中,旨在經過提供類型安全的 contract (協定) 來簡化處理來自 Activity 的數據。這些 協定 爲一些常見操做 (好比: 拍照或請求權限) 定義了預期的輸入和輸出類型,除此以外您還可以 自定義協定 來知足不一樣場景的需求。函數
ActivityResult API
提供了一些組件用於註冊 Activity 的處理結果、發起請求以及在系統返回結果後當即進行相應處理。您也能夠在啓動 Activity 的地方使用一個獨立的類接收返回結果,這樣依然可以保證類型安全。gradle
接下來咱們經過一個打開文檔的示例,來演示如何使用 ActivityResult
API。ui
首先,您須要在 gradle 文件中添加如下依賴:google
repositories { google() maven() } dependencies { // 在 https://developer.android.google.cn/jetpack/androidx/releases/activity 得到最新版本號 def activity_version = "1.2.0" // 在 https://developer.android.google.cn/jetpack/androidx/releases/fragment 得到最新版本號 def fragment_version = "1.3.0" implementation "androidx.activity:activity:$activity_version" implementation "androidx.fragment:fragment:$fragment_version」 }
您須要在協定中註冊一個 回調,在其中定義它輸入輸出的類型。code
在下列代碼中,GetContent() 指的是 ACTION_GET_DOCUMENT intent,它是在 Activity 庫中已定義好的默認協定之一。您能夠在這裏找到完整的 已定義協定列表。component
val getContent = registerForActivityResult(GetContent()) { uri: Uri? -> // 處理返回的 Uri }
如今咱們須要使用返回的 launcher 來啓動咱們的 Activity。您能夠設置一個 mime 類型的過濾器對所選文件進行過濾,GetContent.launch() 接收一個字符串做爲參數:
val getContent = registerForActivityResult(GetContent()) { uri: Uri? -> // 處理返回的 Uri } override fun onCreate(savedInstanceState: Bundle?) { // ... val selectButton = findViewById<Button>(R.id.select_button) selectButton.setOnClickListener { // 傳入您想讓用戶選擇的 mime 類型做爲輸入 getContent.launch("image/*") } }
一旦圖片被選中並返回到您的 Activity,就會攜帶着預期結果執行您以前註冊的回調函數。正如您看到的代碼片斷,ActivityResult 在處理來自 Activity 的返回數據時帶來了更便捷的開發體驗。
如今就使用最新穩定版的 Activity
和 Fragment
庫,經過 ActivityResult
API 以類型安全的方式處理您的 Intent 結果吧!
咱們也但願聽到來自各位開發者的反饋,若是您有任何建議或意見,均可以在這裏給咱們 提交反饋。