Skip to content

Commit

Permalink
avoid Npe for adapter.
Browse files Browse the repository at this point in the history
A NPE was reported for ConversationsListActivity.kt:537

Adapter is accessed with !! while it is not safe to access in term of lifecycle.
So there could have been a race condition.
The overall problem is not solved and may even have to wait for migration to Compose.
This is just a quickfix for v21.0.0

Reported crash was :

Exception java.lang.NullPointerException:
  at com.nextcloud.talk.conversationlist.ConversationsListActivity.filterConversation (ConversationsListActivity.kt:537)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity.setConversationList (ConversationsListActivity.kt:472)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity.access$setConversationList (ConversationsListActivity.kt:158)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity$initObservers$5$1.invokeSuspend (ConversationsListActivity.kt:398)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity$initObservers$5$1.invoke (Unknown Source:8)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity$initObservers$5$1.invoke (Unknown Source:4)
  at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1$2.emit (Emitters.kt:219)
  at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catchImpl$2.emit (Errors.kt:154)
  at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1$2.emit (Emitters.kt:220)
  at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl (SharedFlow.kt:392)
  at kotlinx.coroutines.flow.SharedFlowImpl.collect (Unknown Source)
  at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1.collect (SafeCollector.common.kt:112)
  at kotlinx.coroutines.flow.FlowKt__ErrorsKt.catchImpl (Errors.kt:152)
  at kotlinx.coroutines.flow.FlowKt.catchImpl (Unknown Source:1)
  at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catch$$inlined$unsafeFlow$1.collect (SafeCollector.common.kt:112)
  at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1.collect (SafeCollector.common.kt:112)
  at kotlinx.coroutines.flow.FlowKt__CollectKt.collect (Collect.kt:26)
  at kotlinx.coroutines.flow.FlowKt.collect (Unknown Source:1)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity$initObservers$5.invokeSuspend (ConversationsListActivity.kt:399)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith (DispatchedContinuation.kt:363)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable (Cancellable.kt:26)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default (Cancellable.kt:21)
  at kotlinx.coroutines.CoroutineStart.invoke (CoroutineStart.kt:88)
  at kotlinx.coroutines.AbstractCoroutine.start (AbstractCoroutine.kt:123)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch (Builders.common.kt:52)
  at kotlinx.coroutines.BuildersKt.launch (Unknown Source:1)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default (Builders.common.kt:43)
  at kotlinx.coroutines.BuildersKt.launch$default (Unknown Source:1)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity.initObservers (ConversationsListActivity.kt:395)
  at com.nextcloud.talk.conversationlist.ConversationsListActivity.onCreate (ConversationsListActivity.kt:261)
  at android.app.Activity.performCreate (Activity.java:9149)
  at android.app.Activity.performCreate (Activity.java:9127)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1526)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:4152)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4361)
  at android.app.ActivityThread.handleRelaunchActivityInner (ActivityThread.java:6446)
  at android.app.ActivityThread.handleRelaunchActivity (ActivityThread.java:6329)
  at android.app.servertransaction.ActivityRelaunchItem.execute (ActivityRelaunchItem.java:82)
  at android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:60)
  at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem (TransactionExecutor.java:174)
  at android.app.servertransaction.TransactionExecutor.executeTransactionItems (TransactionExecutor.java:109)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:81)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2747)
  at android.os.Handler.dispatchMessage (Handler.java:112)
  at android.os.Looper.loopOnce (Looper.java:268)
  at android.os.Looper.loop (Looper.java:384)
  at android.app.ActivityThread.main (ActivityThread.java:8921)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:580)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:907)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
  • Loading branch information
mahibi committed Feb 21, 2025
1 parent 8aeaffa commit 17f43e8
Showing 1 changed file with 26 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class ConversationsListActivity :
// Filter Conversations
if (!hasFilterEnabled()) filterableConversationItems = conversationItems
filterConversation()
adapter!!.updateDataSet(filterableConversationItems, false)
adapter?.updateDataSet(filterableConversationItems, false)
Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong())

// Fetch Open Conversations
Expand Down Expand Up @@ -534,7 +534,7 @@ class ConversationsListActivity :
binding.noArchivedConversationLayout.visibility = View.GONE
}

adapter!!.updateDataSet(newItems, true)
adapter?.updateDataSet(newItems, true)
setFilterableItems(newItems)
if (archiveFilterOn) {
// Never a notification from archived conversations
Expand Down Expand Up @@ -735,9 +735,9 @@ class ConversationsListActivity :
supportActionBar?.setTitle(R.string.nc_forward_to_three_dots)
} else {
searchItem!!.isVisible = conversationItems.size > 0
if (adapter!!.hasFilter()) {
if (adapter?.hasFilter() == true) {
showSearchView(searchView, searchItem)
searchView!!.setQuery(adapter!!.getFilter(String::class.java), false)
searchView!!.setQuery(adapter?.getFilter(String::class.java), false)
}
binding.searchText.setOnClickListener {
showSearchView(searchView, searchItem)
Expand Down Expand Up @@ -768,20 +768,20 @@ class ConversationsListActivity :
searchItem!!.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
initSearchDisposable()
adapter!!.setHeadersShown(true)
adapter?.setHeadersShown(true)
if (!hasFilterEnabled()) filterableConversationItems = searchableConversationItems
adapter!!.updateDataSet(filterableConversationItems, false)
adapter!!.showAllHeaders()
adapter?.updateDataSet(filterableConversationItems, false)
adapter?.showAllHeaders()
binding.swipeRefreshLayoutView?.isEnabled = false
searchBehaviorSubject.onNext(true)
return true
}

override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
adapter!!.setHeadersShown(false)
adapter?.setHeadersShown(false)
if (!hasFilterEnabled()) filterableConversationItems = conversationItemsWithHeader
adapter!!.updateDataSet(filterableConversationItems, false)
adapter!!.hideAllHeaders()
adapter?.updateDataSet(filterableConversationItems, false)
adapter?.hideAllHeaders()
if (searchHelper != null) {
// cancel any pending searches
searchHelper!!.cancelSearch()
Expand Down Expand Up @@ -1158,8 +1158,8 @@ class ConversationsListActivity :
val lastVisibleItem = layoutManager!!.findLastCompletelyVisibleItemPosition()
for (flexItem in conversationItems) {
val conversation: ConversationModel = (flexItem as ConversationItem).model
val position = adapter!!.getGlobalPositionOf(flexItem)
if (hasUnreadItems(conversation) && position > lastVisibleItem) {
val position = adapter?.getGlobalPositionOf(flexItem)
if (position != null && hasUnreadItems(conversation) && position > lastVisibleItem) {
nextUnreadConversationScrollPosition = position
if (!binding.newMentionPopupBubble.isShown) {
binding.newMentionPopupBubble.visibility = View.VISIBLE
Expand Down Expand Up @@ -1239,7 +1239,7 @@ class ConversationsListActivity :
val filter = searchQuery
searchQuery = ""
performFilterAndSearch(filter)
} else if (adapter!!.hasNewFilter(newText)) {
} else if (adapter?.hasNewFilter(newText) == true) {
performFilterAndSearch(newText)
}
}
Expand All @@ -1250,12 +1250,12 @@ class ConversationsListActivity :

if (hasFilterEnabled()) {
adapter?.updateDataSet(conversationItems)
adapter!!.setFilter(filter)
adapter!!.filterItems()
adapter?.setFilter(filter)
adapter?.filterItems()
adapter?.updateDataSet(filterableConversationItems)
} else {
adapter!!.setFilter(filter)
adapter!!.filterItems()
adapter?.setFilter(filter)
adapter?.filterItems()
}

if (isUnifiedSearchAvailable(currentUser!!.capabilities!!.spreedCapability!!)) {
Expand All @@ -1268,18 +1268,18 @@ class ConversationsListActivity :

private fun resetSearchResults() {
clearMessageSearchResults()
adapter!!.setFilter("")
adapter!!.filterItems()
adapter?.setFilter("")
adapter?.filterItems()
}

private fun clearMessageSearchResults() {
val firstHeader = adapter!!.getSectionHeader(0)
val firstHeader = adapter?.getSectionHeader(0)
if (firstHeader != null && firstHeader.itemViewType == MessagesTextHeaderItem.VIEW_TYPE) {
adapter!!.removeSection(firstHeader)
adapter?.removeSection(firstHeader)
} else {
adapter!!.removeItemsOfType(MessageResultItem.VIEW_TYPE)
adapter?.removeItemsOfType(MessageResultItem.VIEW_TYPE)
}
adapter!!.removeItemsOfType(LoadMoreResultsItem.VIEW_TYPE)
adapter?.removeItemsOfType(LoadMoreResultsItem.VIEW_TYPE)
}

@SuppressLint("CheckResult") // handled by helper
Expand Down Expand Up @@ -1308,7 +1308,7 @@ class ConversationsListActivity :
}

override fun onItemClick(view: View, position: Int): Boolean {
val item = adapter!!.getItem(position)
val item = adapter?.getItem(position)
if (item != null) {
when (item.itemViewType) {
MessageResultItem.VIEW_TYPE -> {
Expand Down Expand Up @@ -1461,7 +1461,7 @@ class ConversationsListActivity :
if (showShareToScreen || !networkMonitor.isOnline.value) {
Log.d(TAG, "sharing to multiple rooms not yet implemented. onItemLongClick is ignored.")
} else {
val clickedItem: Any? = adapter!!.getItem(position)
val clickedItem: Any? = adapter?.getItem(position)
if (clickedItem != null && clickedItem is ConversationItem) {
val conversation = clickedItem.model
conversationsListBottomDialog = ConversationsListBottomDialog(
Expand Down Expand Up @@ -2012,7 +2012,7 @@ class ConversationsListActivity :
adapterItems.add(LoadMoreResultsItem)
}

adapter!!.addItems(0, adapterItems)
adapter?.addItems(0, adapterItems)
binding.recyclerView?.scrollToPosition(0)
}
}
Expand Down

0 comments on commit 17f43e8

Please sign in to comment.