lateinit property not assigned value soon enough?

265 Views Asked by At

My code works 9,999 out of 10,000 times. But, for about once in every 10,000 times, the application crashes to a UninitializedPropertyAccessException This is problematic as there are about 20,000~30,000 Android devices with my code in production.

It appears that, sometimes, the actual assignment of the lateinit variable is not happening soon enough (and hence causing the exception above).

Has anybody else had a similar problem? What was your solution?

TcpService.kt

class TcpService: Service() {
    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")
    }

    // ...

}
2

There are 2 best solutions below

3
On

Instead of making the property null and then null check which can be dangerous in some scenarios, you can use isInitialized method on your lateInit properties :

    when (intent.action) {
        if (::mTcpClient.isInitialized) { ACTION_SEND_MESSAGE ->
          mTcpClient.sendMessageAsync(intent.getStringExtra(EXTRA_NEW_MESSAGE)
        }
    }
0
On

ahh it happened to me once and i wasted whole day then i solved it(still dont know how) but why dont you make mTcpClient null and then null check:

 `when(intent.action) {
 // This will cause an Uninitialized Property Exception 1 in 10,000 times
                ACTION_SEND_MESSAGE ->{
if(mTcpClient != null){
mTcpClient.sendMessageAsync(intent.getStringExtra(EXTRA_NEW_MESSAGE)  
}else{
mTcpClient=mTcpClient()
mTcpClient.sendMessageAsync(intent.getStringExtra(EXTRA_NEW_MESSAGE)
}
  }
    }`

something like that im not a professional sorry