diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt index d5b5ec6a0dc1..8cfad8c98301 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt @@ -17,18 +17,17 @@ package com.ichi2.anki import android.annotation.SuppressLint -import android.os.Looper import com.ichi2.libanki.Collection import com.ichi2.libanki.CollectionV16 import com.ichi2.libanki.Storage.collection import com.ichi2.libanki.importCollectionPackage +import com.ichi2.utils.Threads import kotlinx.coroutines.* import net.ankiweb.rsdroid.Backend import net.ankiweb.rsdroid.BackendFactory import net.ankiweb.rsdroid.Translations import timber.log.Timber import java.io.File -import java.lang.RuntimeException object CollectionManager { /** @@ -224,21 +223,6 @@ object CollectionManager { return logUIHangs { runBlocking { withCol { this } } } } - private fun isMainThread(): Boolean { - return try { - Looper.getMainLooper().thread == Thread.currentThread() - } catch (exc: RuntimeException) { - if (exc.message?.contains("Looper not mocked") == true) { - // When unit tests are run outside of Robolectric, the call to getMainLooper() - // will fail. We swallow the exception in this case, and assume the call was - // not made on the main thread. - false - } else { - throw exc - } - } - } - /** Execute [block]. If it takes more than 100ms of real time, Timber an error like: > Blocked main thread for 2424ms: com.ichi2.anki.DeckPicker.onCreateOptionsMenu(DeckPicker.kt:624) @@ -250,7 +234,7 @@ object CollectionManager { val start = System.currentTimeMillis() return block().also { val elapsed = System.currentTimeMillis() - start - if (isMainThread() && elapsed > 100) { + if (Threads.isOnMainThread && elapsed > 100) { val stackTraceElements = Thread.currentThread().stackTrace // locate the probable calling file/line in the stack trace, by filtering // out our own code, and standard dalvik/java.lang stack frames diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/Threads.kt b/AnkiDroid/src/main/java/com/ichi2/utils/Threads.kt index d55ac24e1bfd..859efb69464f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/Threads.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/Threads.kt @@ -20,6 +20,7 @@ import android.os.Looper import androidx.annotation.UiThread import androidx.annotation.WorkerThread import timber.log.Timber +import java.lang.RuntimeException /** * Helper class for checking for programming errors while using threads. @@ -29,8 +30,20 @@ object Threads { /** * @return true if called from the application main thread */ - private val isOnMainThread: Boolean - get() = Looper.getMainLooper() == Looper.myLooper() + val isOnMainThread: Boolean + get() = + try { + Looper.getMainLooper().thread == Thread.currentThread() + } catch (exc: RuntimeException) { + if (exc.message?.contains("Looper not mocked") == true) { + // When unit tests are run outside of Robolectric, the call to getMainLooper() + // will fail. We swallow the exception in this case, and assume the call was + // not made on the main thread. + false + } else { + throw exc + } + } /** * Checks that it is called from the main thread and fails if it is called from another thread.