ActivityResultRegistry 是推荐的方法
ComponentActivity 现在提供了一个ActivityResultRegistry,让您可以处理startActivityForResult()+onActivityResult() 以及requestPermissions()+onRequestPermissionsResult() 流,而无需覆盖Activity 或Fragment 中的方法,带来更多通过ActivityResultContract 进行类型安全,并提供用于测试这些流程的挂钩。
强烈建议使用 Android 10 Activity 1.2.0-alpha02 和 Fragment 1.3.0-alpha02 中引入的 Activity Result API。
将此添加到您的build.gradle
def activity_version = "1.2.0-beta01"
// Java language implementation
implementation "androidx.activity:activity:$activity_version"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"
如何使用预建合约
这个新的 API 具有以下预建功能
- 拍摄视频
- 挑选联系人
- 获取内容
- 获取内容
- 打开文档
- 打开文档
- 打开文档树
- 创建文档
- 拨号
- 拍照
- 请求权限
- 请求权限
使用 takePicture 合约的示例:
private val takePicture = prepareCall(ActivityResultContracts.TakePicture()) { bitmap: Bitmap? ->
// Do something with the Bitmap, if present
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener { takePicture() }
}
那么这里发生了什么?让我们稍微分解一下。 takePicture 只是一个回调,它返回一个可为空的位图——它是否为空取决于 onActivityResult 进程是否成功。 prepareCall 然后将此调用注册到ComponentActivity 上的一个新功能中,称为ActivityResultRegistry - 我们稍后再讨论。 ActivityResultContracts.TakePicture() 是 Google 为我们创建的内置助手之一,最后调用 takePicture 实际上会触发 Intent,就像您之前使用 Activity.startActivityForResult(intent, REQUEST_CODE) 一样。
如何编写自定义合同
一个简单的契约,它接受一个 Int 作为 input 并返回一个字符串,请求的 Activity 在结果 Intent 中返回该字符串。
class MyContract : ActivityResultContract<Int, String>() {
companion object {
const val ACTION = "com.myapp.action.MY_ACTION"
const val INPUT_INT = "input_int"
const val OUTPUT_STRING = "output_string"
}
override fun createIntent(input: Int): Intent {
return Intent(ACTION)
.apply { putExtra(INPUT_INT, input) }
}
override fun parseResult(resultCode: Int, intent: Intent?): String? {
return when (resultCode) {
Activity.RESULT_OK -> intent?.getStringExtra(OUTPUT_STRING)
else -> null
}
}
}
class MyActivity : AppCompatActivity() {
private val myActionCall = prepareCall(MyContract()) { result ->
Log.i("MyActivity", "Obtained result: $result")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
button.setOnClickListener {
myActionCall(500)
}
}
}
查看this official documentation了解更多信息。