Реализация обратного вызова в Realm и установка его в MVP ведущего для асинхронной работы - PullRequest
0 голосов
/ 06 июня 2018

В первой задаче я загружал асинхронные данные, и когда я выполнил 1 метод из докладчика, я вызвал второй метод, но мои данные все еще загружаются в этот момент.Итак, после этого я решил эту проблему, и мне нужно установить некоторые обратные вызовы для методов области, чтобы быть уверенными, что мои данные загружены, а после загрузки мне нужно получить их из базы данных и отразить в представлении.Но у меня есть некоторые проблемы с интерфейсом реализации.Каков наилучший способ сделать это?Я постараюсь написать следующий код:

В моем докладчике:

getViewState().showListProgress();
    repository.loadDataFromNetworkToDB();

    List<Anime> animeList = repository.loadDataFromDbToPresenter();
    if (animeList.size() == 0) {
        System.out.println("you are loosing!S");
        Throwable error = new Throwable();
        onLoadingFailed(error);
    } else {
        onLoadingFinish();
        onLoadingSuccess(animeList);
    }

Моя базовая функция для сохранения данных в Realm:

public void saveToDatabase(final OnTransactionCallback onTransactionCall) {
    try {

        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                for (Anime a : animeList) {
                    Anime anime = new Anime();
                    anime.setFromEntity(a);
                    System.out.println("title: " + anime.getTitle() + " saveToDb: ");
                    realm.copyToRealmOrUpdate(anime);
                }
            }
        }, new Realm.Transaction.OnSuccess() {
            @Override
            public void onSuccess() {
                if (onTransactionCall != null) {
                    onTransactionCall.onRealmSuccess();
                }
            }
        }, new Realm.Transaction.OnError() {
            @Override
            public void onError(Throwable error) {
                if (onTransactionCall != null) {
                    onTransactionCall.onRealmError();
                }
            }
        });
    } finally {
        if (realm != null) {
            realm.close();
        }
    }
}

public interface OnTransactionCallback {
    boolean onRealmSuccess();

    boolean onRealmError();
}

После этого яскачать данные из сети и использовать две функции в модели:

public void loadDataFromNetworkToDB() {
    Realm realm = Realm.getDefaultInstance();

    ghibliService.getAnimeList()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(list -> {
                AnimeDbHelper dbHelper = new AnimeDbHelper(realm, list);
                dbHelper.saveToDatabase(this);
            });
}

@Override
public List<Anime> loadDataFromDbToPresenter() {
    List<Anime> animeList = new ArrayList<>();
    Realm realm = Realm.getDefaultInstance();
    try {
        final RealmResults<Anime> animeResults = realm.where(Anime.class).findAll();
        for (int i = 0; i < animeResults.size(); i++) {
            animeList.add(animeResults.get(i).toEntity());
        }
    } finally {
        if (realm != null) {
            realm.close();
        }
    }
    return animeList;

}

@Override
public boolean onRealmSuccess() {
    System.out.println("Success");
    return true;
}

@Override
public boolean onRealmError() {
    System.out.println("Error");
    return false;
}

1 Ответ

0 голосов
/ 07 июня 2018

Хорошо, этот код, приведенный ниже, решает мою проблему, но после того, как я получаю обновленные объекты списка, я улавливаю такие исключения:

I/art: Background sticky concurrent mark sweep GC freed 5614(449KB) AllocSpace objects, 18(288KB) LOS objects, 33% free, 1691KB/2MB, paused 5.354ms total 10.731ms
I/art: Background sticky concurrent mark sweep GC freed 7039(557KB) AllocSpace objects, 22(352KB) LOS objects, 39% free, 1561KB/2MB, paused 10.554ms total 15.931ms 

Очевидно, у докладчика должен быть свой жизненный цикл, и где-то нам нужно удалитьliveData.В моей модели:

public RealmLiveData<Anime> findAnimes() {
    Realm realm = Realm.getDefaultInstance();
    RealmLiveData<Anime> realmLiveData;
    try {
        realmLiveData = new RealmLiveData<>(realm.where(Anime.class).findAllAsync());
    } finally {
        if (realm != null) {
            realm.close();
        }
    }
    return realmLiveData;
}

В моем докладчике:

@Override
public void loadData() {
    view.onDataStarted();

    repository.getAnimeFromNetwork();

    liveData = repository.findAnimes();

    liveData.observeForever(new Observer<RealmResults<Anime>>() {
        @Override
        public void onChanged(@Nullable RealmResults<Anime> animes) {
            if (animes != null) {
                if (animes.size() == 0) {
                    //nothing
                    System.out.println("Result realmResult: " + animes.size());
                } else {
                    view.onDataCompleted();
                    System.out.println("My result before Background sticky concurrent mark sweep GC: " + animes.size());
                    List<Anime> animeList = new ArrayList<>();
                    animeList.addAll(animes);
                    view.showData(animeList);
                    //Trying to stop liveData - helplessness
                    liveData.removeObserver(this::onChanged);
                }
            } else {
                System.out.println("null" + animes);
            }
        }
    });

RealmLiveData:

public class RealmLiveData<T extends RealmModel> extends LiveData<RealmResults<T>> {
private RealmResults<T> results;
private final RealmChangeListener<RealmResults<T>> listener =
        new RealmChangeListener<RealmResults<T>>() {
            @Override
            public void onChange(RealmResults<T> results) {
                setValue(results);
            }
        };
public RealmLiveData(RealmResults<T> realmResults) {
    results = realmResults;
}
@Override
protected void onActive() {
    results.addChangeListener(listener);
}
@Override
protected void onInactive() {
    results.removeChangeListener(listener);
}
...