You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用支付触发Can't create handler异常的解决方案咨询

异常分析与解决方案

异常栈追踪

FATAL EXCEPTION: DefaultDispatcher-worker-5
Process: com.shoptheworldonline.android, PID: 5088
java.lang.RuntimeException: Can't create handler inside thread Thread[DefaultDispatcher-worker-5,5,main] that has not called Looper.prepare()
at android.os.Handler.(Handler.java:227)
at android.os.Handler.(Handler.java:129)
at android.app.Activity.(Activity.java:925)
at androidx.core.app.ComponentActivity.(ComponentActivity.java:51)
at androidx.activity.ComponentActivity.(ComponentActivity.java:282)
at androidx.fragment.app.FragmentActivity.(FragmentActivity.java:108)
at androidx.appcompat.app.AppCompatActivity.(AppCompatActivity.java:96)
at com.example.shoptheworld.android.utils.ErrorService.(ErrorService.kt:23)
at com.example.shoptheworld.android.PaymentActivity.callPaymentMethod(PaymentActivity.kt:413)
at com.example.shoptheworld.android.PaymentActivity.access$callPaymentMethod(PaymentActivity.kt:60)
at com.example.shoptheworld.android.PaymentActivity$onCreate$4$1.invokeSuspend(PaymentActivity.kt:239)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@898620e, Dispatchers.IO]

问题根源

  1. 类设计错误:ErrorService错误继承了AppCompatActivity,但它本质是工具类而非UI组件。Android的Activity必须由系统通过Intent启动,不能手动调用构造函数实例化。
  2. 线程错误:在后台线程(DefaultDispatcher-worker-5,对应Dispatchers.IO)中实例化了ErrorService,而Activity构造内部会创建Handler,非主线程默认未初始化Looper,直接触发异常。

解决方案

1. 重构ErrorService类

移除对AppCompatActivity的继承,改为普通工具类,通过传入Context实现相关功能:

// 错误写法
class ErrorService : AppCompatActivity() {
    // ... 原有代码
}

// 正确写法
class ErrorService(private val context: Context) {
    // 错误处理逻辑
}

2. 确保UI操作在主线程执行

如果ErrorService包含Toast、弹窗等UI操作,必须切换到主线程:

// 在ErrorService中添加UI操作方法
fun showError(message: String) {
    (context as? Activity)?.runOnUiThread {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
}

// 或用协程切换主线程
fun showErrorWithCoroutine(message: String) {
    CoroutineScope(Dispatchers.Main).launch {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
}

3. 修正PaymentActivity的调用逻辑

在callPaymentMethod中正确实例化ErrorService,并确保协程调度器合理使用:

// 错误写法
fun callPaymentMethod() {
    // 后台线程中实例化继承Activity的ErrorService
    val errorService = ErrorService()
}

// 正确写法
fun callPaymentMethod() {
    val errorService = ErrorService(this) // 传入当前Activity的Context
    // 处理支付错误时调用
    errorService.showError("支付失败,请重试")
}

// 协程中正确切换调度器示例
lifecycleScope.launch {
    // 后台执行支付请求
    val paymentResult = withContext(Dispatchers.IO) {
        paymentApi.processPayment()
    }
    // 主线程处理结果
    if (paymentResult.isFailure) {
        ErrorService(this@PaymentActivity).showError(paymentResult.errorMessage)
    }
}

内容的提问来源于stack exchange,提问作者Hari Krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:48:29