Android Activity Result API

·  阅读 1014

最近准备开始新的项目,在编写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:$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: 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
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改