Rx Java - несколько сложные запросы API, вместе с деталями прогресса - PullRequest
0 голосов
/ 06 января 2020

Начнем с того, что я играю с RxJava / Rx Android только пару дней.

В psuedocode я пытаюсь выполнить sh что-то подобное при загрузке данных. из API Guild Wars 2:

refreshDatabase {
    getAllIds - single API call (50.000+ ids)
    chunk ids into chunks of 100 each
    for each chunk
        getItems - single API call which fetches 100 items
        update ui on the progress (# chunks out of # chunks done)
    loop through all items when all chunks are fetched
        determine if the item is something we're after
            save it in our own database
        update ui on progress (# items out of # items done)
    return bool telling if successful or not
}

Я прочитал много учебников и документации по этому поводу, но я не совсем понимаю, как это кодировать.

I ' мы закончили и работаем с логиками c для всего этого, если я хочу, чтобы сортировка / сохранение в базе данных выполнялись сразу после получения чанка, но тогда я не могу обновить пользовательский интерфейс с подробностями.

Поскольку это операция, которая занимает много времени при первом запуске, я бы хотел, чтобы прогресс был довольно подробным, а не экономил 0,5-2 секунды времени загрузки.

Любые советы о том, как я получить сделать что-то вроде того, что я положил в psuedocode?

1 Ответ

0 голосов
/ 07 января 2020

Разделите завоевателя.

На самом деле у вас есть 2 или 3 разных операции, поэтому не пытайтесь делать это в одной функции.

Прежде всего, вы должны использовать WorkManager из AndroidX Jetpack для выполнения синхронизации c локальной БД и Room для чтения и записи в локальную База данных SQLite.

Начиная с извлечения всех соответствующих элементов и сохранения их в вашей БД (без выполнения обновлений пользовательского интерфейса здесь):

class MyRepository(private val api: MyApi, private val dao:MyItemDao) {
    fun isItemInteresting(item: Item): Boolean {
        return true
    }

    fun fetchAllInterestingItems(): Single<List<Item>> {
        return api.getAllIds()
            .flatMapIterable { it }
            .buffer(100)
            .flatMap { api.getItems(it) }
            .flatMapIterable { it }
            .filter { isItemInteresting(it) }
            .toList()
    }

    fun updateDatabase(items: List<Item>): Completable {
        return dao.storeItems(items)
    }
}

class SyncWorker(
    context: Context,
    params: WorkerParameters,
    private val repository: MyRepository
) : RxWorker(context, params) {
    override fun createWork(): Single<Result> {
        return repository.fetchAllInterestingItems()
            .flatMapCompletable { repository.updateDatabase(it) }
            .subscribeOn(Schedulers.io())
            .toSingle { Result.success()}
    }
}

Это приведет к извлечению всех элементов, проверке соответствующих элементов и сохранению их в ваша база данных (MyApi будет интерфейсом Retrofit, а MyItemDao - интерфейс Room Dao).

Отчет о прогрессе в пользовательском интерфейсе может быть выполнен через API отчетности о прогрессе в WorkManager (версия 2.3.0, в настоящее время в бета-версии).

...