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]
问题根源
- 类设计错误:
ErrorService错误继承了AppCompatActivity,但它本质是工具类而非UI组件。Android的Activity必须由系统通过Intent启动,不能手动调用构造函数实例化。 - 线程错误:在后台线程(
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
相关产品推荐
相关产品推荐

