浏览代码

fix NPE in restoreMessageQueue

currentConversation was not yet initialized in ChatActivity.
In the future this may be better handled via StateFlows. For now it's solved via arguments.

Without the fix, this NPE appeared:

Exception java.lang.RuntimeException:
  at android.app.ActivityThread.performResumeActivity (ActivityThread.java:4768)
  at android.app.ActivityThread.handleResumeActivity (ActivityThread.java:4801)
  at android.app.servertransaction.ResumeActivityItem.execute (ResumeActivityItem.java:54)
  at android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:45)
  at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:176)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2215)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:346)
  at android.os.Looper.loop (Looper.java:475)
  at android.app.ActivityThread.main (ActivityThread.java:7889)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1009)
Caused by java.lang.NullPointerException:
  at com.nextcloud.talk.chat.MessageInputFragment.onResume (MessageInputFragment.kt:146)
  at androidx.fragment.app.Fragment.performResume (Fragment.java:3180)
  at androidx.fragment.app.FragmentStateManager.resume (FragmentStateManager.java:606)
  at androidx.fragment.app.FragmentStateManager.moveToExpectedState (FragmentStateManager.java:285)
  at androidx.fragment.app.FragmentStore.moveToExpectedState (FragmentStore.java:113)
  at androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1433)
  at androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:2977)
  at androidx.fragment.app.FragmentManager.dispatchResume (FragmentManager.java:2909)
  at androidx.fragment.app.FragmentController.dispatchResume (FragmentController.java:285)
  at androidx.fragment.app.FragmentActivity.onResumeFragments (FragmentActivity.java:334)
  at androidx.fragment.app.FragmentActivity.onPostResume (FragmentActivity.java:323)
  at androidx.appcompat.app.AppCompatActivity.onPostResume (AppCompatActivity.java:245)
  at android.app.Activity.performResume (Activity.java:8215)
  at android.app.ActivityThread.performResumeActivity (ActivityThread.java:4758)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 5 月之前
父节点
当前提交
f144b64365

+ 13 - 4
app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt

@@ -411,12 +411,11 @@ class ChatActivity :
         setContentView(binding.root)
         setupSystemColors()
 
-        messageInputFragment = MessageInputFragment()
-
         conversationUser = currentUserProvider.currentUser.blockingGet()
-
         handleIntent(intent)
 
+        messageInputFragment = getMessageInputFragment()
+
         chatViewModel = ViewModelProvider(this, viewModelFactory)[ChatViewModel::class.java]
 
         messageInputViewModel = ViewModelProvider(this, viewModelFactory)[MessageInputViewModel::class.java]
@@ -457,6 +456,15 @@ class ChatActivity :
         }
     }
 
+    private fun getMessageInputFragment(): MessageInputFragment {
+        val internalId = conversationUser!!.id.toString() + "@" + roomToken
+        return MessageInputFragment().apply {
+            arguments = Bundle().apply {
+                putString(CONVERSATION_INTERNAL_ID, internalId)
+            }
+        }
+    }
+
     override fun onNewIntent(intent: Intent) {
         super.onNewIntent(intent)
         val extras: Bundle? = intent.extras
@@ -990,7 +998,7 @@ class ChatActivity :
             } else {
                 supportFragmentManager.commit {
                     setReorderingAllowed(true)
-                    replace(R.id.fragment_container_activity_chat, MessageInputFragment())
+                    replace(R.id.fragment_container_activity_chat, getMessageInputFragment())
                 }
             }
         }
@@ -3784,5 +3792,6 @@ class ChatActivity :
         private const val RESUME_AUDIO_TAG = "RESUME_AUDIO_TAG"
         private const val DELAY_TO_SHOW_PROGRESS_BAR = 1000L
         private const val FIVE_MINUTES_IN_SECONDS: Long = 300
+        const val CONVERSATION_INTERNAL_ID = "CONVERSATION_INTERNAL_ID"
     }
 }

+ 8 - 4
app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt

@@ -111,6 +111,7 @@ class MessageInputFragment : Fragment() {
     lateinit var networkMonitor: NetworkMonitor
 
     lateinit var binding: FragmentMessageInputBinding
+    private lateinit var conversationInternalId: String
     private var typedWhileTypingTimerIsRunning: Boolean = false
     private var typingTimer: CountDownTimer? = null
     private lateinit var chatActivity: ChatActivity
@@ -122,6 +123,10 @@ class MessageInputFragment : Fragment() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         sharedApplication!!.componentApplication.inject(this)
+        conversationInternalId = arguments?.getString(ChatActivity.CONVERSATION_INTERNAL_ID).orEmpty()
+        if (conversationInternalId.isEmpty()) {
+            Log.e(TAG, "internalId for conversation passed to MessageInputFragment is empty")
+        }
     }
 
     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@@ -143,7 +148,7 @@ class MessageInputFragment : Fragment() {
 
     override fun onResume() {
         super.onResume()
-        chatActivity.messageInputViewModel.restoreMessageQueue(chatActivity.currentConversation!!.internalId)
+        chatActivity.messageInputViewModel.restoreMessageQueue(conversationInternalId)
     }
 
     override fun onDestroyView() {
@@ -728,9 +733,8 @@ class MessageInputFragment : Fragment() {
         }
     }
 
-    private fun isTypingStatusEnabled(): Boolean {
-        return !CapabilitiesUtil.isTypingStatusPrivate(chatActivity.conversationUser!!)
-    }
+    private fun isTypingStatusEnabled(): Boolean =
+        !CapabilitiesUtil.isTypingStatusPrivate(chatActivity.conversationUser!!)
 
     private fun uploadFile(fileUri: String, isVoiceMessage: Boolean, caption: String = "", token: String = "") {
         var metaData = ""