Rx Java и запрос Realm заставляют приложение пропустить кадр - PullRequest
0 голосов
/ 09 марта 2020

Я использую Rx Java и базу данных Realm в проекте android. Но иногда нажатие кнопки не отвечает, и вам приходится делать это много раз, чтобы она работала когда-нибудь, а android log сообщает, что кадр xxx пропущен. Я знаю, что это связано с неправильным использованием потока пользовательского интерфейса. Вот некоторые из моих запросов, может кто-нибудь сказать мне, что с ними не так? Realm хочет, чтобы я выполнил запрос ввода-вывода в том же потоке, в котором я использую ответ (хотя и не уверен).

public Flowable<List<ClothingItem>> getClothingItemsLocal() {
    return Flowable.just(dbProvider.getClothingItems(mSortType));
}

public Flowable<List<ClothingItem>> getClothingItemsRemote() {
    return clothingService.getAll("Bearer " + preferencesManager.getToken())
            .map(response -> response.items)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSuccess(clothingItems -> {
                dbProvider.clearClothingItems();
                dbProvider.saveOrUpdateClothingItems(clothingItems);
            })
            .toFlowable()
            .map(remoteItems -> dbProvider.getClothingItems(mSortType));
}

public Flowable<ClothingItem> getClothingItem(@NonNull final String id) {
    return getClothingItemRemote(id)
            .startWith(dbProvider.getClothingItem(id))
            .onErrorReturn(throwable -> dbProvider.getClothingItem(id));
}

Метод getAll с модификацией.

@GET(BuildConfig.BASE_API_PATH + "clothing_items")
Single<GetClothingItemsResponseModel> getAll(@Header("Authorization") String token);

Методы провайдера области:

public void saveOrUpdateEvents(List<Event> data) {
    realmInstance.executeTransaction(realm -> {
        for (Event event : data) {
            if (!TextUtils.isEmpty(event.date)) {
                Date date = DateUtils.getFullDate(event.date);
                Timber.d("date %s", date.toString());
                event.timestamp = date;
            }
            Event cashedEvent = getEvent(event.id);
            if (cashedEvent.id != null) {
                event.eventClothingItems = cashedEvent.eventClothingItems;
                event.tags = cashedEvent.tags;
                event.location = cashedEvent.location;
            }
        }
        realm.delete(Event.class);
        realm.insertOrUpdate(data);
    });
}



public void clearClothingItems() {
    realmInstance.executeTransaction(realm -> {
        realm.delete(ClothingItem.class);
    });
}

1 Ответ

0 голосов
/ 09 марта 2020

Попробуйте это:

public Flowable<List<ClothingItem>> getClothingItemsRemote() {
    return clothingService.getAll("Bearer " + preferencesManager.getToken())         
            .subscribeOn(Schedulers.io())   
            .map(response -> response.items) 
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSuccess(clothingItems -> {
                dbProvider.clearClothingItems();
                dbProvider.saveOrUpdateClothingItems(clothingItems);
            })     
            .observeOn(Schedulers.computation())
            .toFlowable()
            .map(remoteItems -> dbProvider.getClothingItems(mSortType));
}
...