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具有以下预构建的功能
TakeVideo
PickContact
GetContent
GetContents
OpenDocument
opendocument
OpenDocumentTree
CreateDocument
刻度盘
TakePicture
RequestPermission
RequestPermissions
下面的例子使用了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() }
}
So what’s going on here? Let’s break it down slightly. takePicture is just a callback which returns a nullable Bitmap - whether or not it’s null depends on whether or not the onActivityResult process was successful. prepareCall then registers this call into a new feature on ComponentActivity called the ActivityResultRegistry - we’ll come back to this later. ActivityResultContracts.TakePicture() is one of the built-in helpers which Google have created for us, and finally invoking takePicture actually triggers the Intent in the same way that you would previously with Activity.startActivityForResult(intent, REQUEST_CODE).
如何编写自定义合同
一个简单的契约,它接受一个Int作为输入,并返回一个被请求的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)
}
}
}
查看官方文档了解更多信息。