最近准备开始新的项目,在编写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 : FragmentActivity() {
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: FragmentActivity() {
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 : FragmentActivity() {
//默认合约
var forActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
launcher?.text="lanuncher callback value : resultCode:${activityResult.resultCode} data:${activityResult.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: FragmentActivity() {
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()
}
}
}
示例效果图:
在非Activity和Fragment的类中接收ActivityResult
示例代码如下:
class A : FragmentActivity() {
var myActivityResultObserver : MyActivityResultObserver? = null
override fun onStart() {
myActivityResultObserver = MyActivityResultObserver(activityResultRegistry)
lifecycle.addObserver(myActivityResultObserver)
super.onStart()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myActivityResultObserver.launch(Intent(this@AActivity, B::class.java))
}
}
class MyActivityResultObserver(private val registry: ActivityResultRegistry) : DefaultLifecycleObserver {
private var activityResultLauncher : ActivityResultLauncher<Intent>? = null
override fun onStart(owner: LifecycleOwner) {
super.onCreate(owner)
activityResultLauncher = registry.register("MyActivityResultReceiver", owner, ActivityResultContracts.StartActivityForResult()) {
}
}
fun launch(input: Intent) {
activityResultLauncher?.launch(input)
}
}
今天的文章Android Activity Result API分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18175.html