android - 在 Realm 中实现回调并将其设置在 Presenter MVP 中以进行异步工作
问题描述
在第一个问题中,我的方式是加载异步数据,当我完成演示者的 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);
}
我将数据保存到领域的基本功能:
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;
}
解决方案
好的,下面的这段代码解决了我的问题,但是在我获得更新的列表对象后,我捕获了这样的异常:
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
显然,presenter 应该有自己的生命周期,并且在某个地方我们需要删除 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);
}
}
});
RealmLive 数据:
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);
}
推荐阅读
- html - 如何在 div 中使用和插入 SVG 文件
- nlp - 使用 GPT3 构建一个模型来回答来自数据集的问题
- linux - 在启用 TCP 保持活动选项时获取无效参数作为失败原因?
- google-apps-script - 从 Google Apps Script Web 应用程序获取 JSON 从另一个网络应用程序获取 JSON,无需匿名访问
- python - Django REST 序列化程序,如何添加额外的字段并设置它
- r - ggplot2 单个图中的多个 geom_point
- java - 是否有一个更简单的术语代表“非破坏性设置器”?
- django - 从客户端完成文件上传时的 Django FileField/ImageField 验证
- javascript - R闪亮:checkboxGroupInput在复选框之间插入地标
- sql - 在同一列中获取上一行