Сопрограмма Котлина приостановить ошибку с Room DataSource.Factory - PullRequest
0 голосов
/ 17 октября 2019

Обзор

Ожидается - Успешное выполнение запроса Room для DataSource.Factory<Int, Content> для заполнения PagedList. Эта стратегия аналогична реализации Room ? Coroutines , описанной в публикации Medium Florina Muntenescu из команды разработчиков Android Developer Advocate.

Observed - Приложение не может быть построено.

Ошибка

К сожалению, нет более конкретной ошибки, чтобы указать источник проблемы.

Произошел сбой при выполнении org.jetbrains.kotlin.gradle.internal.KaptExecution

Реализация

ViewModel

  1. ViewModel использует viewModelScope для запуска getContentList().
  2. getContentList() - это функция приостановки, которая вызывает хранилище с другой функцией приостановки getMainFeedList().
  3. В случаях Loading и Error выполняется вызов Room queryMainContentList(...).
class ContentViewModel : ViewModel() {
    fun processEvent(...) {
        ...
        viewModelScope.launch {
            _feedViewState.value = FeedViewState(contentList = getContentList(...))
        }
        ...
    }

    suspend private fun getContentList(...): LiveData<PagedList<Content>> =
            switchMap(getMainFeedList(isRealtime, timeframe)) { lce ->
                when (lce) {
                    is Loading -> 
                       coroutineScope { 
                          emitSource(queryMainContentList(...)) 
                       }
                    is Lce.Content -> lce.packet.pagedList!!
                    is Error -> 
                       coroutineScope { 
                          emitSource(queryMainContentList(...)) 
                       }
                }
            }
}

Репозиторий

  1. getMainFeedList() - это функция приостановки, которая использует withContext(Dispatchers.Default) для получения области сопрограмм.
  2. getMainFeedList() возвращает LiveData с результатом запроса коллекции Firefase Firestore, contentEnCollection.get().addOnCompleteListener.
  3. Результат Firestore сохраняется в DB Room с insertContentList() изнутри вложенной приостановленной сопрограммы launch { ... }. insertContentList() работает должным образом, используя suspend.
object ContentRepository {
    fun getMainFeedList(...) =  liveData<Lce<PagedListResult>> {
            val lce = this
            val newContentList = arrayListOf<Content?>()
            contentEnCollection.get().addOnCompleteListener {
                arrayListOf<Content?>().also { contentList ->
                    it.result!!.documents.all { document ->
                        contentList.add(document.toObject(Content::class.java))
                        true
                    }
                    newContentList.addAll(contentList)
                }
                CoroutineScope(Dispatchers.Default).launch {
                   try {
                      database.contentDao().insertContentList(newContentList)
                   } catch (e: Exception) {
                      this.cancel()
                   }
                }.invokeOnCompletion { throwable ->
                   if (throwable == null)
                      lce.emit(Lce.Content(PagedListResult(
                         pagedList = queryMainContentList(timeframe),
                         errorMessage =  "")))
                   else // Log Room error.
                }
            }.addOnFailureListener {
                // Log Firestore error here.
                lce.emit(...)
            }
        }
    }
}

suspend fun queryMainContentList(timestamp: Timestamp) =
            liveDataBuilder(database.contentDao().queryMainContentList(timestamp, MAIN))

fun liveDataBuilder(dataSource: DataSource.Factory<Int, Content>) =
        LivePagedListBuilder(dataSource,
                PagedList.Config.Builder().setEnablePlaceholders(true)
                        .setPrefetchDistance(PREFETCH_DISTANCE)
                        .setPageSize(PAGE_SIZE)
                        .build())
                .build()

Дао

insertContentList() работает какожидается.

@Dao
interface ContentDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertContentList(users: ArrayList<Content?>)

    @Query("SELECT * FROM content WHERE timestamp >= :timeframe AND feedType = :feedType ORDER BY timestamp DESC")
    suspend fun queryMainContentList(timeframe: Timestamp, feedType: FeedType): DataSource.Factory<Int, Content>
}

Трассировка стека

Важная часть выглядит следующим образом:

Ошибка: не уверен, как конвертироватьКурсор для типа возврата этого метода (androidx.paging.DataSource.Factory).

Вот полный журнал:

21: 50: 30:Выполнение задачи «assemblyAndroidTest» ...

Выполнение задач: [assemblyAndroidTest] в проекте / Users / adamhurwitz / Coinverse / android

Настройка проекта: приложение ПРЕДУПРЕЖДЕНИЕ: Следующие параметры проекта устарели и имеютбыл удален: android.databinding.enableV2 Привязка данных v1 удалена.

ПРЕДУПРЕЖДЕНИЕ. Настройка параметра 'android.enableR8.fullMode = true' является экспериментальной и не поддерживается. Текущее значение по умолчанию - «false».

ПРЕДУПРЕЖДЕНИЕ: API 'option.getAssemble ()' устарел и был заменен на 'variable.getAssembleProvider ()'. Он будет удален в конце 2019 года. Для получения дополнительной информации см. https://d.android.com/r/tools/task-configuration-avoidance. Чтобы определить, что вызывает option.getAssemble (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ПРЕДУПРЕЖДЕНИЕ. API 'OptionOutput.getProcessResources ()' устарел и был заменен на 'OptionOutput.getProcessResourcesProvider ()'. Он будет удален в конце 2019 года. Для получения дополнительной информации см. https://d.android.com/r/tools/task-configuration-avoidance. Чтобы определить, что вызывает optionOutput.getProcessResources (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ПРЕДУПРЕЖДЕНИЕ. API 'OptionOutput.getProcessManifest ()' устарел и был заменен на 'OptionOutput.getProcessManifestProvider ()'. Он будет удален в конце 2019 года. Для получения дополнительной информации см. https://d.android.com/r/tools/task-configuration-avoidance.. Чтобы определить, что вызывает optionOutput.getProcessManifest (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ВНИМАНИЕ: API-интерфейс устарел и был заменен на

https://d.android.com/r/tools/task-configuration-avoidance. Чтобы определить, что вызывает option.getMergeResources (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ВНИМАНИЕ: API-интерфейс устарел и был заменен на https://d.android.com/r/tools/task-configuration-avoidance. To чтобы определить, что вызывает option.getMergeAssets (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ПРЕДУПРЕЖДЕНИЕ: API-интерфейс «option.getPackageApplication ()» устарел и был заменен на «variable.getPackageApplicationProvider ()». Он будет удален в конце 2019 года. Для получения дополнительной информации см. https://d.android.com/r/tools/task-configuration-avoidance. Чтобы определить, что вызывает option.getPackageApplication (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации. ПРЕДУПРЕЖДЕНИЕ: API 'option.getExternalNativeBuildTasks ()' устарел и был заменен на 'variable.getExternalNativeBuildProviders ()'. Он будет удален в конце 2019 года. Для получения дополнительной информации см. https://d.android.com/r/tools/task-configuration-avoidance. Чтобы определить, что вызывает option.getExternalNativeBuildTasks (), используйте -Pandroid.debug.obsoleteApi = true в командной строке для отображения дополнительной информации.

Задача: app: preBuild UP-TO-DATE Задача: app: preDebugBuild UP-TO-DATE Задача: app: mergeDebugShaders UP-TO-DATE Задача: app: compileDebugShaders UP-TO-DATE Задача: app:Задача UPD-DATE для createDebugAssets Задача: app: processDebugGoogleServices Задача UP-TO-DATE: app: checkDebugManifest Задача UP-TO-DATE: app: createDebugCompatibleScreenManifests Задача UP-TO-DATE: app: mainApkListPersistenceDebug Приложение UP-TO-DATEgenerateDebugBuildConfig UP-TO-DATE Задача: app: compileDebugAidl NO-SOURCE Задача: app: compileDebugRenderscript NO-SOURCE Задача: app: mergeDebugAssets UP-TO-DATE Задача: app: processDebugManifest Задача UP-TO-DATE: app: fabricDeneratees: writeDebugApplicationId UP-TO-DATE Задача: app: generateSafeArgsDebug UP-TO-DATE Задача: app: prepareLintJar UP-TO-DATE Задача: app: prepareLintJarForPublish UP-TO-DATE. Задача: app: generateDebugSources. Задача: app: dataBindingExportBuildInfoDebug. UP-TO-DATE. -TO-DATE Задача: app: generateDebugResources UP-TO-DATE. Задача: app: dataBindingExportFeaturePackageIdsDebug. UP-TO-DATE. приложение: compileDebugAndroidTestRenderscript NO-SOURCE Задача: приложение: generateDebugAndroidTestBuildConfig UP-TO-DATE Задача: приложение: mainApkListPersistenceDebugAndroidTest UP-TO-DATE Задача: приложение: generateDebugAndroidTestResValues ​​UP-TO-DATE Задача: приложение: generateDebugAndroidTestResources UP-TO-DATE Задача: приложение:mergeDebugAndroidTestResources UP-TO-DATE Задача: app: processDebugAndroidTestResources UP-TO-DATE Задача: app: mergeDebugAndroidTestShaders UP-TO-DATE Задача: app: compileDebugAndroidTestShaders UP-TO-DATE Задача: app: generateDebugAndroidTestAssets UP-TO-DATE Задача: app: mergeDebugAndroidTestAssets UP-TO-DATE Задача: app: processDebugAndroidTestJavaRes NO-SOURCE Задача: app: mergeDebugAndroidTestJniLibDDLIBLIBT TOF-DATE-TO-DATE Задача: app: checkDebugAndroidTestDuplicateClasses UP-TO-DATE Задача: app: validateSigningDebugAndroidTest UP-TO-DATE Задача: app: signatureConfigWriterDebugAndroidTest UP-TO-DATE / Пользователи / adamhurwitz / Совмещенный / промежуточный / промежуточный / app //mergeDebugResources/merged.dir/values/values.xml:1002: warn: множественные замены указаны в непозиционном формате;Вы хотели добавить атрибут formatted = "false"? /Users/adamhurwitz/Coinverse/android/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:1031: warn: множественные замены указаны в непозиционном формате;Вы хотели добавить атрибут formatted = "false"?.

Задача: app: mergeDebugResources Задача: app: dataBindingGenBaseClassesDebug UP-TO-DATE Задача: app: processDebugResources Задача: app: kaptGenerateStubsDebugKotlin UP-TO-DATE

Задача: app: kaptDebugKotlin FAILEDANTLR Tool версии 4.5.3, используемая для генерации кода, не соответствует текущей версии среды выполнения 4.7.1ANTLR Runtime версии 4.5.3, используемой для компиляции синтаксического анализатора, не соответствует текущей версии среды выполнения 4.7.1ANTLR Tool версии 4.5.3, используемой для генерации кода, не соответствуетсоответствует текущей версии среды выполнения 4.7.1ANTLR Версия 4.5.3 среды выполнения, используемая для компиляции синтаксического анализатора, не соответствует версии среды выполнения 4.7.1 / Users / adamhurwitz / Coinverse / android / app / build / tmp / kapt3 / заглушки / debug / app /coinverse / content / room / ContentDao.java: 17: ошибка: Не уверен, как преобразовать курсор в тип возвращаемого значения этого метода (androidx.paging.DataSource.Factory). общедоступный аннотацияне являются инкрементными: androidx.lifecycle.LifecycleProcessor (NON_INCREMENTAL). ^ FAILURE: сборка не удалась с исключением.

  • Что пошло не так: выполнение задачи не выполнено ': app: kaptDebugKotlin'. Aпроизошла ошибка при выполнении> org.jetbrains.kotlin.gradle.internal.KaptExecution java.lang.reflect.InvocationTargetException (без сообщения об ошибке)

  • Try: Запустите с параметром --stacktrace, чтобы получитьтрассировка стека. Запустите с параметром --info или --debug, чтобы получить больше выходных данных журнала. Запустите с --scan, чтобы получить полное представление.

  • Получите дополнительную справку по https://help.gradle.org

СБОЙ ПОСТРОЕНИЯ в 9s 38 выполнимых задач: 4 выполнено, 34 актуально 21:50:40: Выполнение задачи завершено, «buildAndroidTest».

1 Ответ

1 голос
/ 24 октября 2019

Нет варианта использования, чтобы пометить метод Dao как suspend, который создает DataSource.Factory. Тип возврата просто используется процессором аннотации, чтобы узнать, какой код генерировать (как модификатор suspend). Источник данных при использовании вместе с LiveData<PagedList> всегда будет выполнять запросы вне основного потока, чтобы вы могли безопасно вызывать неподдерживаемую базу данных и блокировать сетевые вызовы. Кроме того, нет смысла отмечать любой метод Dao, который возвращает LiveData, как подлежащий приостановке, поскольку ArchTaskExecutor гарантирует, что запросы выполняются из потока пользовательского интерфейса, но результаты доставляются в потоке пользовательского интерфейса.

КомуДля создания LiveData, вызывающего приостановленные методы, вы можете использовать расширение liveData {} из артефакта lifecycle-livedata-ktx.

Существует также LiveData-builder, который создает LiveData<PagedList> непосредственно из вашего DataSource.Factory, проверьте paging-runtime-ktx артефакт.

Кроме того, я бы не рекомендовал возвращать MutableLiveData таким образом. Изменяемые жилаты обычно мутируют в приватном режиме и возвращаются как неизменяемый объект LiveData.

...