From 40a08394bcb24c2a5b6f1cf79c84036e903c64c0 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Tue, 1 Jun 2021 13:37:58 +0200 Subject: [PATCH] hardened view binding interaction ...in case of asynchronous UI interaction with already destroyed UI Signed-off-by: Andy Scherzinger --- .../talk/controllers/ChatController.kt | 34 ++++++++++++++----- .../controllers/base/NewBaseController.kt | 4 +++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index 3da3ccd74..c42ee5544 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -267,12 +267,18 @@ class ChatController(args: Bundle) : loadAvatarForStatusBar() setTitle() - setupMentionAutocomplete() - checkReadOnlyState() - checkLobbyState() + try { + setupMentionAutocomplete() + checkReadOnlyState() + checkLobbyState() - if (!inConversation) { - joinRoomWithPassword() + if (!inConversation) { + joinRoomWithPassword() + } + } catch (npe: NullPointerException) { + // view binding can be null + // since this is called asynchrously and UI might have been destroyed in the meantime + Log.i(TAG, "UI destroyed - view binding already gone") } } @@ -559,7 +565,7 @@ class ChatController(args: Bundle) : } private fun checkReadOnlyState() { - if (currentConversation != null) { + if (currentConversation != null && isAlive()) { if (currentConversation?.shouldShowLobby(conversationUser) ?: false || currentConversation?.conversationReadOnlyState != null && currentConversation?.conversationReadOnlyState == @@ -589,7 +595,10 @@ class ChatController(args: Bundle) : } private fun checkLobbyState() { - if (currentConversation != null && currentConversation?.isLobbyViewApplicable(conversationUser) ?: false) { + if (currentConversation != null && + currentConversation?.isLobbyViewApplicable(conversationUser) ?: false && + isAlive() + ) { if (!checkingLobbyStatus) { getRoomInfo() @@ -773,7 +782,7 @@ class ChatController(args: Bundle) : } private fun setupMentionAutocomplete() { - if (!isDestroyed && !isBeingDestroyed) { + if (isAlive()) { val elevation = 6f resources?.let { val backgroundDrawable = ColorDrawable(it.getColor(R.color.bg_default)) @@ -968,7 +977,14 @@ class ChatController(args: Bundle) : currentConversation?.sessionId setupWebsocket() - checkLobbyState() + + try { + checkLobbyState() + } catch (npe: NullPointerException) { + // view binding can be null + // since this is called asynchrously and UI might have been destroyed in the meantime + Log.i(TAG, "UI destroyed - view binding already gone") + } if (isFirstMessagesProcessing) { pullChatMessages(0) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt b/app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt index 17c7ebecf..101524787 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/base/NewBaseController.kt @@ -101,6 +101,10 @@ abstract class NewBaseController(@LayoutRes var layoutRes: Int, args: Bundle? = cleanTempCertPreference() } + fun isAlive(): Boolean { + return !isDestroyed && !isBeingDestroyed + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup,