From b45d6e7a5a2fb9b5759c72f128955cb017cf5f3a Mon Sep 17 00:00:00 2001 From: Dima Date: Fri, 27 Dec 2024 11:23:16 +0900 Subject: [PATCH] Fix for PdfReaderViewModel.loadAnnotations ANR triggered by main thread waiting for too long Upping versionCode to 125 --- .../requests/ReadAnnotationsDbRequest.kt | 2 +- .../android/pdf/reader/PdfReaderViewModel.kt | 42 ++++++++++--------- .../android/sync/AnnotationConverter.kt | 8 ++-- buildSrc/src/main/kotlin/BuildConfig.kt | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/zotero/android/database/requests/ReadAnnotationsDbRequest.kt b/app/src/main/java/org/zotero/android/database/requests/ReadAnnotationsDbRequest.kt index 45d8adbf..b4a69b2b 100644 --- a/app/src/main/java/org/zotero/android/database/requests/ReadAnnotationsDbRequest.kt +++ b/app/src/main/java/org/zotero/android/database/requests/ReadAnnotationsDbRequest.kt @@ -30,6 +30,6 @@ class ReadAnnotationsDbRequest( .deleted(false) .`in`("annotationType", supportedTypes.toTypedArray()) .sort("annotationSortIndex", Sort.ASCENDING) - .findAll() + .findAllAsync() } } \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt index 7a608f74..3772f1f8 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt @@ -62,6 +62,7 @@ import io.realm.RealmResults import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.debounce @@ -70,6 +71,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import okhttp3.internal.toHexString import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe @@ -197,6 +199,7 @@ class PdfReaderViewModel @Inject constructor( private val schemaController: SchemaController, private val dateParser: DateParser, private val navigationParamsMarshaller: NavigationParamsMarshaller, + private val dispatcher: CoroutineDispatcher, stateHandle: SavedStateHandle, ) : BaseViewModel2(PdfReaderViewState()), PdfReaderVMInterface { @@ -473,7 +476,9 @@ class PdfReaderViewModel @Inject constructor( this@PdfReaderViewModel.pdfFragment.addDocumentListener(object : DocumentListener { override fun onDocumentLoaded(document: PdfDocument) { - this@PdfReaderViewModel.onDocumentLoaded(document) + viewModelScope.launch { + this@PdfReaderViewModel.onDocumentLoaded(document) + } } override fun onDocumentClick(): Boolean { @@ -584,7 +589,7 @@ class PdfReaderViewModel @Inject constructor( } - private fun onDocumentLoaded(document: PdfDocument) { + private suspend fun onDocumentLoaded(document: PdfDocument) { this.document = document annotationBoundingBoxConverter = AnnotationBoundingBoxConverter(document) loadRawDocument() @@ -778,11 +783,11 @@ class PdfReaderViewModel @Inject constructor( } } - private fun loadAnnotations( + private suspend fun loadAnnotations( document: PdfDocument, username: String, displayName: String - ): Map { + ): Map = withContext(dispatcher){ val annotations = mutableMapOf() val pdfAnnotations = document.annotationProvider .getAllAnnotationsOfTypeAsync(AnnotationsConfig.supported) @@ -799,17 +804,15 @@ class PdfReaderViewModel @Inject constructor( color = pdfAnnotation.color.toHexString(), username = username, displayName = displayName, - boundingBoxConverter = this.annotationBoundingBoxConverter + boundingBoxConverter = this@PdfReaderViewModel.annotationBoundingBoxConverter ) ?: continue annotations[annotation.key] = annotation } - - return annotations - + annotations } - private fun loadDocumentData() { + private suspend fun loadDocumentData() { val key = viewState.key val library = viewState.library val dbResult = loadAnnotationsAndPage(key = key, library = library) @@ -2396,16 +2399,17 @@ class PdfReaderViewModel @Inject constructor( private fun addDocumentListener2() { this.pdfFragment.addDocumentListener(object : DocumentListener { override fun onDocumentLoaded(document: PdfDocument) { - this@PdfReaderViewModel.onDocumentLoaded(document) - - if (queuedUpPdfReaderColorPickerResult != null) { - setToolOptions( - hex = queuedUpPdfReaderColorPickerResult!!.colorHex, - size = queuedUpPdfReaderColorPickerResult!!.size, - tool = queuedUpPdfReaderColorPickerResult!!.annotationTool - ) - queuedUpPdfReaderColorPickerResult = null - + viewModelScope.launch { + this@PdfReaderViewModel.onDocumentLoaded(document) + + if (queuedUpPdfReaderColorPickerResult != null) { + setToolOptions( + hex = queuedUpPdfReaderColorPickerResult!!.colorHex, + size = queuedUpPdfReaderColorPickerResult!!.size, + tool = queuedUpPdfReaderColorPickerResult!!.annotationTool + ) + queuedUpPdfReaderColorPickerResult = null + } } } diff --git a/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt b/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt index a38faab3..41822a45 100644 --- a/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt +++ b/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt @@ -13,6 +13,8 @@ import com.pspdfkit.annotations.TextMarkupAnnotation import com.pspdfkit.annotations.UnderlineAnnotation import com.pspdfkit.document.PdfDocument import io.realm.RealmResults +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import org.json.JSONObject import org.zotero.android.database.objects.AnnotationType import org.zotero.android.database.objects.AnnotationsConfig @@ -39,7 +41,7 @@ class AnnotationConverter { companion object { - fun annotations( + suspend fun annotations( items: RealmResults, type: Kind = zotero, currentUserId: Long, @@ -48,8 +50,8 @@ class AnnotationConverter { username: String, boundingBoxConverter: AnnotationBoundingBoxConverter, isDarkMode: Boolean, - ): List { - return items.mapNotNull { item -> + ): List = withContext(Dispatchers.IO) { + items.mapNotNull { item -> val annotation = PDFDatabaseAnnotation.init(item) ?: return@mapNotNull null annotation( zoteroAnnotation = annotation, diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index 8be82bb0..60e2d7bf 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -4,7 +4,7 @@ object BuildConfig { const val compileSdkVersion = 34 const val targetSdk = 34 - val versionCode = 124 // Must be updated on every build + val versionCode = 125 // Must be updated on every build val version = Version( major = 1, minor = 0,