使用举例
实现原理
通过封装Activity Result API
,将Intent中的参数全部放在一个Parcelable对象上(这个对象的key是特殊的_extra_
),而不是将参数一个一个的通过intent.putExtra()
来传递, 可以减少很多静态变量如INTENT_KEY_XX
的声明
具体代码
kotlin
// ActivityResultKt.kt类
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract
const val INTENT_EXTRA = "_extra_"
fun <PI : Parcelable?, PO : Parcelable> ComponentActivity.registerResult(
activityClass: Class<*>,
onResult: (resultCode: Int, out: PO?) -> Unit
): ActivityResultLauncher<PI?> {
return registerForActivityResult(StartActivityForResultContract(activityClass)) { r ->
val ext = r.data?.getParcelableExtra(INTENT_EXTRA) as? PO
onResult(r.resultCode, ext)
}
}
class StartActivityForResultContract<T : Parcelable?>(private val activityClass: Class<*>) :
ActivityResultContract<T, ActivityResult>() {
override fun createIntent(context: Context, input: T): Intent {
val intent = Intent(context, activityClass)
intent.putExtra(INTENT_EXTRA, input)
if (context !is Activity) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
return intent
}
override fun parseResult(resultCode: Int, intent: Intent?): ActivityResult = ActivityResult(resultCode, intent)
}
fun <PI : Parcelable?> ComponentActivity.getExtra(): PI? = intent.getParcelableExtra(INTENT_EXTRA) as? PI
fun <PO : Parcelable> ComponentActivity.setResult(resultCode: Int, out: PO) {
val intent = Intent()
intent.putExtra(INTENT_EXTRA, out)
setResult(resultCode, intent)
}
如何使用
- 将以上
ActivityResultKt.kt
类复制到项目中,Fragment
请自行实现 - 定义
ActivityB
需要的输入参数类,例如参数有studentId
kotlin
@Parcelize // 该注解来自 id 'kotlin-parcelize' 插件
data class InExtra(val studentId: String): Parcelable
- 定义
ActivityA
需要的返回结果类,例如需要studentName
kotlin
@Parcelize
data class OutExtra(val studentName: String): Parcelable
- 在
ActivityA
定义启动器
kotlin
// 若不需要输入,可以填Nothing, registerResult<Nothing, OutExtra>
val activityLauncher = registerResult<InExtra, OutExtra>(ActivityB::class.java) { resultCode, out ->
}
- 在需要的地方跳转到
ActivityB
kotlin
activityLauncher.launch(InExtra(studentId = "123"))
- 在
ActivityB
中将结果返回
kotlin
// val inExtra = getExtra<InExtra>() 取出输入值
setResult(RESULT_OK, OutExtra(studentName = "飞羽"))
finish()