Android Kotlin中startActivityForResult()废弃问题的解决方案
替换废弃的startActivityForResult()方案(结合PaymentActivity与协程)
核心方案:使用Activity Result API替代废弃方法
Android官方推荐用Activity Result API替换startActivityForResult(),同时结合协程在PaymentActivity中处理后台支付逻辑,避免阻塞UI线程。
步骤1:在主Activity中注册Activity Result Launcher
在主Activity的onCreate()方法中(或更早的生命周期阶段)注册启动器,用于接收PaymentActivity返回的结果:
import androidx.activity.result.contract.ActivityResultContracts class MainActivity : AppCompatActivity() { // 注册Activity Result Launcher private val paymentResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { val data = result.data // 处理PaymentActivity返回的结果,比如支付成功状态、订单号等 val isPaymentSuccess = data?.getBooleanExtra("PAYMENT_SUCCESS", false) ?: false val testId = data?.getStringExtra("TEST_ID") if (isPaymentSuccess && testId != null) { // 支付成功后的逻辑,比如跳转至AttemptTestActivity val intent = Intent(this, AttemptTestActivity::class.java).apply { putExtra("Test_Id", testId) putExtra("Category_Id", category_id) putExtra("Result_Auto_Publish", result_auto_publish) } startActivity(intent) } } else if (result.resultCode == RESULT_CANCELED) { // 支付取消或失败的处理逻辑 Toast.makeText(this, "支付已取消", Toast.LENGTH_SHORT).show() } } // 原onClickJoin方法修改 fun onClickJoin(view: View) { if (binding.joinNowTxt.text.toString() == resources.getString(R.string.join_now)) { val paymentIntent = Intent(this, PaymentActivity::class.java).apply { putExtra("PAYMENT_AMOUNT", test_list[position].joinAmount.toFloat().toInt()) putExtra("TEST_ID", test_list[position].testId) } // 用launch替代废弃的startActivityForResult paymentResultLauncher.launch(paymentIntent) } else { bindingPayment.choosePaymentLayout.visibility = View.GONE if (isAttemp == 2) { val intent = Intent(applicationContext, AttemptTestActivity::class.java).apply { putExtra("Test_Id", test_list[position].testId) putExtra("Category_Id", category_id) putExtra("Result_Auto_Publish", result_auto_publish) } Log.e("Intent Data", "Starting AttemptTestActivity") startActivity(intent) } } } }
步骤2:PaymentActivity中用协程处理支付逻辑并返回结果
在PaymentActivity中,使用lifecycleScope(或ViewModel的viewModelScope)启动协程处理支付,避免阻塞UI线程,处理完成后返回结果给主Activity:
import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class PaymentActivity : AppCompatActivity() { private lateinit var binding: PaymentActivityBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = PaymentActivityBinding.inflate(layoutInflater) setContentView(binding.root) // 获取传递的支付参数 val paymentAmount = intent.getIntExtra("PAYMENT_AMOUNT", 0) val testId = intent.getStringExtra("TEST_ID") ?: "" // 支付按钮点击事件 binding.payButton.setOnClickListener { // 用lifecycleScope启动协程,在IO线程处理支付逻辑 lifecycleScope.launch { val paymentSuccess = processPayment(paymentAmount, testId) // 切回UI线程更新界面并返回结果 withContext(Dispatchers.Main) { val resultIntent = Intent().apply { putExtra("PAYMENT_SUCCESS", paymentSuccess) putExtra("TEST_ID", testId) } setResult(if (paymentSuccess) RESULT_OK else RESULT_CANCELED, resultIntent) finish() } } } } // 模拟支付处理逻辑,实际替换为真实支付SDK调用 private suspend fun processPayment(amount: Int, testId: String): Boolean { return withContext(Dispatchers.IO) { // 这里执行耗时的支付操作,比如调用支付SDK接口 // 模拟网络延迟 kotlinx.coroutines.delay(2000) // 假设支付成功,实际根据接口返回判断 true } } }
关键说明
- Activity Result API:相比旧方法,它将结果回调与启动逻辑解耦,更符合Android架构规范,避免内存泄漏风险。
- 协程处理:通过
lifecycleScope绑定Activity生命周期,确保协程在Activity销毁时自动取消,同时用Dispatchers.IO处理耗时的支付操作,不阻塞UI线程。 - 结果传递:PaymentActivity通过
setResult()将支付状态和参数返回给主Activity,主Activity在Launcher的回调中处理后续逻辑。
内容的提问来源于stack exchange,提问作者Hariom Harsh
相关产品推荐
相关产品推荐

