【发布时间】:2020-09-20 18:04:15
【问题描述】:
我的代码在 10,000 次中运行 9,999 次。但是,大约每 10,000 次,应用程序崩溃到 UninitializedPropertyAccessException 这是有问题的,因为大约有 20,000~30,000 台 Android 设备在生产中使用我的代码。
看起来,lateinit 变量的实际赋值有时并没有很快发生(因此导致上述异常)。
有没有其他人遇到过类似的问题?你的解决方案是什么?
TcpService.kt
类 TcpService:服务(){ private lateinit var mTcpClient: TcpClient
override fun onCreate() {
registerReceiver(object: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when(intent.action) {
// This will cause an Uninitialized Property Exception 1 in 10,000 times
ACTION_SEND_MESSAGE -> mTcpClient.sendMessageAsync(intent.getStringExtra(EXTRA_NEW_MESSAGE)
}
}
}, IntentFilter(ACTION_SEND_MESSAGE)
})
}
override fun onStart() {
mTcpClient = mTcpClient()
}
// ...
}
TcpClient.kt
class TcpClient() {
init {
// ...
sendBroadcast(Intent(ACTION_SEND_MESSAGE).putExtra(EXTRA_NEW_MESSAGE, "Message Contents")
}
// ...
}
【问题讨论】:
-
并发广播发生在
TcpClient对象初始化之前。 -
为什么不在
onCreate()中创建接收者之前移动实例化? -
@Tenfour04 这似乎是显而易见的解决方案,但这篇文章是真实代码的极其简化的版本,我无法在接收者之前实例化 TcpClient
-
@Alirezaa 感谢您指出这一点——这可能是我做错了。我已经重构了我的代码,使其在 init 块中没有广播。只有时间会证明这是否是正确的解决方案,但我很乐观:)
-
在
TcpClient上使用start()方法并将sendBroadcast位放在那里会很糟糕吗?您在这里所做的是在构造函数(包括init块)完成运行之前调用实例上的方法 - 通常通过广播系统存在异步延迟,但我想有时它只是直接立即运行?通过将其作为您在mTcpClient = mTcpClient()之后调用的单独步骤,该字段肯定会被分配