Updated removing of "empty list" messages
Before this commit, the loader removed messages _after_ it updated the list. Coincidentally the list updating mechanism is asynchronous to some extent and so slower devices might've had the message removed after changes have been dispatched which confused the recyclerview and caused the crash. Now, the loader is stripped of the responsibility update the list holding helper messages. The responsibility is for the user itself to notify listeners and then clear the helper list. This should hopefully delay the removal to the point where choreographer had enough time to traverse through the hierarchy. Stupid recycler view / layout managers. Literally unnecessary crash.
This commit is contained in:
parent
0dc9f5c324
commit
851ee81486
@ -1,8 +1,71 @@
|
||||
package com.topjohnwu.magisk.extensions
|
||||
|
||||
import androidx.databinding.ObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
|
||||
|
||||
fun KObservableField<Boolean>.toggle() {
|
||||
value = !value
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> ObservableList<T>.addOnListChangedCallback(
|
||||
onChanged: ((sender: ObservableList<T>) -> Unit)? = null,
|
||||
onItemRangeRemoved: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null,
|
||||
onItemRangeMoved: ((sender: ObservableList<T>, fromPosition: Int, toPosition: Int, itemCount: Int) -> Unit)? = null,
|
||||
onItemRangeInserted: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null,
|
||||
onItemRangeChanged: ((sender: ObservableList<T>, positionStart: Int, itemCount: Int) -> Unit)? = null
|
||||
) = addOnListChangedCallback(object : ObservableList.OnListChangedCallback<ObservableList<T>>() {
|
||||
override fun onChanged(sender: ObservableList<T>?) {
|
||||
onChanged?.invoke(sender ?: return)
|
||||
}
|
||||
|
||||
override fun onItemRangeRemoved(
|
||||
sender: ObservableList<T>?,
|
||||
positionStart: Int,
|
||||
itemCount: Int
|
||||
) {
|
||||
onItemRangeRemoved?.invoke(
|
||||
sender ?: return,
|
||||
positionStart,
|
||||
itemCount
|
||||
)
|
||||
}
|
||||
|
||||
override fun onItemRangeMoved(
|
||||
sender: ObservableList<T>?,
|
||||
fromPosition: Int,
|
||||
toPosition: Int,
|
||||
itemCount: Int
|
||||
) {
|
||||
onItemRangeMoved?.invoke(
|
||||
sender ?: return,
|
||||
fromPosition,
|
||||
toPosition,
|
||||
itemCount
|
||||
)
|
||||
}
|
||||
|
||||
override fun onItemRangeInserted(
|
||||
sender: ObservableList<T>?,
|
||||
positionStart: Int,
|
||||
itemCount: Int
|
||||
) {
|
||||
onItemRangeInserted?.invoke(
|
||||
sender ?: return,
|
||||
positionStart,
|
||||
itemCount
|
||||
)
|
||||
}
|
||||
|
||||
override fun onItemRangeChanged(
|
||||
sender: ObservableList<T>?,
|
||||
positionStart: Int,
|
||||
itemCount: Int
|
||||
) {
|
||||
onItemRangeChanged?.invoke(
|
||||
sender ?: return,
|
||||
positionStart,
|
||||
itemCount
|
||||
)
|
||||
}
|
||||
})
|
@ -13,6 +13,7 @@ import com.topjohnwu.magisk.core.tasks.RepoUpdater
|
||||
import com.topjohnwu.magisk.data.database.RepoByNameDao
|
||||
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.addOnListChangedCallback
|
||||
import com.topjohnwu.magisk.extensions.reboot
|
||||
import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
@ -156,6 +157,21 @@ class ModuleViewModel(
|
||||
}
|
||||
update(subject.module, progress.times(100).roundToInt())
|
||||
}
|
||||
|
||||
itemsInstalled.addOnListChangedCallback(
|
||||
onItemRangeInserted = { sender, _, count ->
|
||||
if (count > 0 || sender.size > 0) {
|
||||
itemsInstalledHelpers.clear()
|
||||
}
|
||||
}
|
||||
)
|
||||
itemsUpdatable.addOnListChangedCallback(
|
||||
onItemRangeInserted = { sender, _, count ->
|
||||
if (count > 0 || sender.size > 0) {
|
||||
itemsUpdatableHelpers.clear()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// ---
|
||||
@ -175,19 +191,13 @@ class ModuleViewModel(
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map {
|
||||
itemsInstalled.update(it.first, it.second)
|
||||
if (itemsInstalled.isNotEmpty())
|
||||
itemsInstalledHelpers.remove(itemNoneInstalled)
|
||||
it.first
|
||||
}
|
||||
.observeOn(Schedulers.io())
|
||||
.map { loadUpdates(it) }
|
||||
.map { it to itemsUpdatable.calculateDiff(it) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnSuccess {
|
||||
itemsUpdatable.update(it.first, it.second)
|
||||
if (itemsUpdatable.isNotEmpty())
|
||||
itemsUpdatableHelpers.remove(itemNoneUpdatable)
|
||||
}
|
||||
.doOnSuccess { itemsUpdatable.update(it.first, it.second) }
|
||||
.ignoreElement()!!
|
||||
|
||||
@Synchronized
|
||||
@ -261,7 +271,7 @@ class ModuleViewModel(
|
||||
@WorkerThread
|
||||
private fun List<ModuleItem>.loadDetail() = onEach { module ->
|
||||
Single.fromCallable { dao.getRepoById(module.item.id)!! }
|
||||
.subscribeK { module.repo = it }
|
||||
.subscribeK(onError = {}) { module.repo = it }
|
||||
.add()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user