Android Activity Result API

Android Activity Result API本篇文章介绍了如何通过官方推荐的Activity Result API替代以往的onActivityResult方法来获取页面的返回值。

最近准备开始新的项目,在编写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()
        }
    }
}

示例效果图: 1642499246411691.gif

在非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

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注