From 924bca4034e8a3a2141a94a55d0445db9cff9c29 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 3 Jul 2022 05:50:25 +1000 Subject: [PATCH] Make sure change notifications fire on the main thread --- .../java/com/ichi2/libanki/ChangeManager.kt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/ChangeManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/ChangeManager.kt index ac70013e400e..71f6ef98f7a0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/ChangeManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/ChangeManager.kt @@ -34,10 +34,12 @@ import anki.collection.OpChangesAfterUndo import anki.collection.OpChangesWithCount import anki.collection.OpChangesWithId import anki.import_export.ImportResponse +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import java.lang.ref.WeakReference object ChangeManager { - interface ChangeSubscriber { + interface Subscriber { /** * Called after a backend method invoked via col.op() or col.opWithProgress() * has modified the collection. Subscriber should inspect the changes, and update @@ -46,14 +48,14 @@ object ChangeManager { fun opExecuted(changes: OpChanges, handler: Any?) } - private val subscribers = mutableListOf>() + private val subscribers = mutableListOf>() - fun subscribe(subscriber: ChangeSubscriber) { + fun subscribe(subscriber: Subscriber) { subscribers.add(WeakReference(subscriber)) } private fun notifySubscribers(changes: OpChanges, handler: Any?) { - val expired = mutableListOf>() + val expired = mutableListOf>() for (subscriber in subscribers) { val ref = subscriber.get() if (ref == null) { @@ -67,7 +69,7 @@ object ChangeManager { } } - fun notifySubscribers(changes: T, initiator: Any?) { + internal fun notifySubscribers(changes: T, initiator: Any?) { val opChanges = when (changes) { is OpChanges -> changes is OpChangesWithCount -> changes.changes @@ -82,8 +84,10 @@ object ChangeManager { /** Wrap a routine that returns OpChanges* or similar undo info with this * to notify change subscribers of the changes. */ -fun undoableOp(handler: Any? = null, block: () -> T): T { +suspend fun undoableOp(handler: Any? = null, block: () -> T): T { return block().also { - ChangeManager.notifySubscribers(it, handler) + withContext(Dispatchers.Main) { + ChangeManager.notifySubscribers(it, handler) + } } }