forked from GitHub-Mirror/riotX-android
Fix ConcurrentModificationException
This commit is contained in:
parent
3e97503220
commit
401f878a9c
@ -88,39 +88,43 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
|
|
||||||
private val listUpdateCallback = object : ListUpdateCallback {
|
private val listUpdateCallback = object : ListUpdateCallback {
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun onChanged(position: Int, count: Int, payload: Any?) {
|
override fun onChanged(position: Int, count: Int, payload: Any?) {
|
||||||
assertUpdateCallbacksAllowed()
|
synchronized(modelCache) {
|
||||||
(position until (position + count)).forEach {
|
assertUpdateCallbacksAllowed()
|
||||||
modelCache[it] = null
|
(position until (position + count)).forEach {
|
||||||
|
modelCache[it] = null
|
||||||
|
}
|
||||||
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
requestModelBuild()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun onMoved(fromPosition: Int, toPosition: Int) {
|
override fun onMoved(fromPosition: Int, toPosition: Int) {
|
||||||
assertUpdateCallbacksAllowed()
|
synchronized(modelCache) {
|
||||||
val model = modelCache.removeAt(fromPosition)
|
assertUpdateCallbacksAllowed()
|
||||||
modelCache.add(toPosition, model)
|
val model = modelCache.removeAt(fromPosition)
|
||||||
requestModelBuild()
|
modelCache.add(toPosition, model)
|
||||||
|
requestModelBuild()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun onInserted(position: Int, count: Int) {
|
override fun onInserted(position: Int, count: Int) {
|
||||||
assertUpdateCallbacksAllowed()
|
synchronized(modelCache) {
|
||||||
(0 until count).forEach {
|
assertUpdateCallbacksAllowed()
|
||||||
modelCache.add(position, null)
|
(0 until count).forEach {
|
||||||
|
modelCache.add(position, null)
|
||||||
|
}
|
||||||
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
requestModelBuild()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun onRemoved(position: Int, count: Int) {
|
override fun onRemoved(position: Int, count: Int) {
|
||||||
assertUpdateCallbacksAllowed()
|
synchronized(modelCache) {
|
||||||
(0 until count).forEach {
|
assertUpdateCallbacksAllowed()
|
||||||
modelCache.removeAt(position)
|
(0 until count).forEach {
|
||||||
|
modelCache.removeAt(position)
|
||||||
|
}
|
||||||
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
requestModelBuild()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,17 +138,21 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
this.timeline?.listener = this
|
this.timeline?.listener = this
|
||||||
|
|
||||||
// Clear cache
|
// Clear cache
|
||||||
for (i in 0 until modelCache.size) {
|
synchronized(modelCache) {
|
||||||
modelCache[i] = null
|
for (i in 0 until modelCache.size) {
|
||||||
|
modelCache[i] = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.eventIdToHighlight != eventIdToHighlight) {
|
if (this.eventIdToHighlight != eventIdToHighlight) {
|
||||||
// Clear cache to force a refresh
|
// Clear cache to force a refresh
|
||||||
for (i in 0 until modelCache.size) {
|
synchronized(modelCache) {
|
||||||
if (modelCache[i]?.eventId == eventIdToHighlight
|
for (i in 0 until modelCache.size) {
|
||||||
|| modelCache[i]?.eventId == this.eventIdToHighlight) {
|
if (modelCache[i]?.eventId == eventIdToHighlight
|
||||||
modelCache[i] = null
|
|| modelCache[i]?.eventId == this.eventIdToHighlight) {
|
||||||
|
modelCache[i] = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.eventIdToHighlight = eventIdToHighlight
|
this.eventIdToHighlight = eventIdToHighlight
|
||||||
@ -194,28 +202,29 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
require(inSubmitList || Looper.myLooper() == backgroundHandler.looper)
|
require(inSubmitList || Looper.myLooper() == backgroundHandler.looper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
private fun getModels(): List<EpoxyModel<*>> {
|
private fun getModels(): List<EpoxyModel<*>> {
|
||||||
(0 until modelCache.size).forEach { position ->
|
synchronized(modelCache) {
|
||||||
// Should be build if not cached or if cached but contains mergedHeader or formattedDay
|
(0 until modelCache.size).forEach { position ->
|
||||||
// We then are sure we always have items up to date.
|
// Should be build if not cached or if cached but contains mergedHeader or formattedDay
|
||||||
if (modelCache[position] == null
|
// We then are sure we always have items up to date.
|
||||||
|| modelCache[position]?.mergedHeaderModel != null
|
if (modelCache[position] == null
|
||||||
|| modelCache[position]?.formattedDayModel != null) {
|
|| modelCache[position]?.mergedHeaderModel != null
|
||||||
modelCache[position] = buildItemModels(position, currentSnapshot)
|
|| modelCache[position]?.formattedDayModel != null) {
|
||||||
}
|
modelCache[position] = buildItemModels(position, currentSnapshot)
|
||||||
}
|
|
||||||
return modelCache
|
|
||||||
.map {
|
|
||||||
val eventModel = if (it == null || collapsedEventIds.contains(it.localId)) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
it.eventModel
|
|
||||||
}
|
|
||||||
listOf(eventModel, it?.mergedHeaderModel, it?.formattedDayModel)
|
|
||||||
}
|
}
|
||||||
.flatten()
|
}
|
||||||
.filterNotNull()
|
return modelCache
|
||||||
|
.map {
|
||||||
|
val eventModel = if (it == null || collapsedEventIds.contains(it.localId)) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
it.eventModel
|
||||||
|
}
|
||||||
|
listOf(eventModel, it?.mergedHeaderModel, it?.formattedDayModel)
|
||||||
|
}
|
||||||
|
.flatten()
|
||||||
|
.filterNotNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -296,16 +305,17 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun searchPositionOfEvent(eventId: String): Int? {
|
fun searchPositionOfEvent(eventId: String): Int? {
|
||||||
// Search in the cache
|
synchronized(modelCache) {
|
||||||
modelCache.forEachIndexed { idx, cacheItemData ->
|
// Search in the cache
|
||||||
if (cacheItemData?.eventId == eventId) {
|
modelCache.forEachIndexed { idx, cacheItemData ->
|
||||||
return idx
|
if (cacheItemData?.eventId == eventId) {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class CacheItemData(
|
private data class CacheItemData(
|
||||||
|
Loading…
Reference in New Issue
Block a user