注册

Android Activity Result API

最近准备开始新的项目,在编写base类复写onActivityResult方法时,发现已经提示deprecation了。于是去官网查找了一下,发现现在官方推荐做法是使用 Activity Result API。

本篇文章用来记录一下 Activity Result API 如何使用。

以往的实现方式

以往,A Activity获取B Activity的返回值的实现方法是,A通过startActivityForResult()来启动B,然后B在finish()之前通过setResult()方法来设置结果值,A就可以在onActivityResult()方法中获取到B在setResult()方法中设置的参数。简单示例如下:

class A : Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startActivityForResult(Intent(this,B::class.java))
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
//从B返回后这里就可以获取到resultCode为Activity.RESULT_OK
}
}

class B: Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setResult(Activity.RESULT_OK)
finish()
}
}

Activity Result API

现在,在Activity和Fragment中,Activity Result API提供了registerForActivityResult()方法,该方法用于注册获取结果的回调。

registerForActivityResult可以传入ActivityResultContract、ActivityResultRegistry、ActivityResultCallback等3个参数,并返回ActivityResultLauncher。

  • ActivityResultContract:ActivityResult合约,约定输入的参数和输出的参数。包含默认合约和自定义合约。
  • ActivityResultRegistry:存储已注册的ActivityResultCallback的记录表,可以在非Activity和Fragment的类中借用此类获取ActivityResult。
  • ActivityResultCallback:ActivityResult回调,用于获取返回结果。
  • ActivityResultLauncher:启动器,根据合约规定的输入参数来启动页面。

Activity Result API的简单使用示例:

class A : Activity() {

//默认合约
var forActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
launcher?.text="lanuncher callback value : resultCode:$resultCode data$data"
}

//自定义合约(输入输出类型均为String)
var forActivityResultLauncher1 = registerForActivityResult(object : ActivityResultContract<String, String>() {
override fun createIntent(context: Context, input: String?): Intent {
return Intent(this@AActivity, B::class.java).apply {
putExtra("inputParams", input)
}
}

override fun parseResult(resultCode: Int, intent: Intent?): String {
return if (resultCode == Activity.RESULT_OK) {
intent?.getStringExtra("result") ?: "empty result"
} else {
""
}
}
}) { resultString ->
launcher1?.text = "lanuncher1 callback value : reslutString:$reslutString"
}

var launcher: TextView? = null
var launcher1: TextView? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_a_activity)
launcher = findViewById(R.id.tv_launcher_callback)
launcher1 = findViewById(R.id.tv_launcher_callback1)
val btnLauncher = findViewById<Button>(R.id.launcher)
val btnLauncher1 = findViewById<Button>(R.id.launcher1)
btnLauncher.setOnClickListener {
//默认合约
forActivityResultLauncher.launch(Intent(this@AActivity, B::class.java))
}

btnLauncher1.setOnClickListener {
//自定义合约
forActivityResultLauncher1.launch("inputParams from A")
}
}
}

class B: Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_b_activity)
val btnBack = findViewById<Button>(R.id.back)
val inputParams = intent.getStringExtra("inputParams")
btnBack.setOnClickListener {
if (TextUtils.isEmpty(inputParams)) {
setResult(Activity.RESULT_OK, Intent())
} else {
setResult(Activity.RESULT_OK, Intent().apply {
putExtra("result", "result from A")
})
}
finish()
}
}
}

示例效果图: 1642499246411691.gif

在非Activity和Fragment的类中接收ActivityResult

示例代码如下:

class A : Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val myActivityResultObserver = MyActivityResultObserver(activityResultRegistry)
lifecycle.addObserver(myActivityResultObserver)
}
}

class MyActivityResultObserver(private val registry: ActivityResultRegistry) : DefaultLifecycleObserver {

override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
registry.register("MyActivityResultReceiver", owner, ActivityResultContracts.StartActivityForResult()) {

}
}
}

作者:ChenYhong
链接:https://juejin.cn/post/7055971438767357965
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册