From c8b2bcb06459ee023430ff7f5a5a2a2c31bb742f Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Fri, 11 Nov 2022 16:33:45 +0300 Subject: [PATCH] android: Fix of StackoverflowError (#1322) * android: Fix of StackoverflowError * Break * Comment * Update apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt * Revert "Update apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt" This reverts commit ea8015e01d7e339042f5062e9db3420142c716c2. Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- .../java/chat/simplex/app/model/SimpleXAPI.kt | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) 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