diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index ccc08306c4..761071ce28 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -264,8 +264,20 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a private fun startReceiver() { Log.d(TAG, "ChatController startReceiver") if (receiverStarted) return - thread(name="receiver") { - GlobalScope.launch { withContext(Dispatchers.IO) { recvMspLoop() } } + receiverStarted = true + CoroutineScope(Dispatchers.IO).launch { + while (true) { + /** Global [ctrl] can be null. It's needed for having the same [ChatModel] that already made in [ChatController] without the need + * to change it everywhere in code after changing a database. + * Since it can be changed in background thread, making this check to prevent NullPointerException */ + val ctrl = ctrl + if (ctrl == null) { + receiverStarted = false + break + } + val msg = recvMsg(ctrl) + if (msg != null) processReceivedMsg(msg) + } } } @@ -291,26 +303,18 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a } } - private suspend fun recvMsg(ctrl: ChatCtrl): CR? { - return withContext(Dispatchers.IO) { - val json = chatRecvMsgWait(ctrl, MESSAGE_TIMEOUT) - if (json == "") { - null - } else { - val r = APIResponse.decodeStr(json).resp - Log.d(TAG, "chatRecvMsg: ${r.responseType}") - if (r is CR.Response || r is CR.Invalid) Log.d(TAG, "chatRecvMsg json: $json") - r - } + private fun recvMsg(ctrl: ChatCtrl): CR? { + val json = chatRecvMsgWait(ctrl, MESSAGE_TIMEOUT) + return if (json == "") { + null + } else { + val r = APIResponse.decodeStr(json).resp + Log.d(TAG, "chatRecvMsg: ${r.responseType}") + if (r is CR.Response || r is CR.Invalid) Log.d(TAG, "chatRecvMsg json: $json") + r } } - private suspend fun recvMspLoop() { - val msg = recvMsg(ctrl ?: return) - if (msg != null) processReceivedMsg(msg) - recvMspLoop() - } - suspend fun apiGetActiveUser(): User? { val r = sendCmd(CC.ShowActiveUser()) if (r is CR.ActiveUser) return r.user