Android RX Observer 到 SQLite 数据库不工作
-
26-12-2019 - |
题
我正在尝试将 RX 观察器添加到我的 SQLite 数据库中,并且我肯定在我的实现中遗漏了一些东西,因为既没有 onNext()
和 onCompleted()
我的观察者的方法没有被调用。
这是我的观察者:
private final Observer<List<Order>> mObjectiveObserver = new Observer<List<Order>>() {
@Override
public void onCompleted() {
System.out.println("Load completed");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Order> objectives) {
System.out.println("On Next: " + objectives.size() + " elements found!");
orderAdapter.clear();
if (objectives != null) {
orderAdapter.addAll(objectives);
mCirclePulseView.setVisibility(View.INVISIBLE);
} else {
mCirclePulseView.setVisibility(View.VISIBLE);
}
orderAdapter.notifyDataSetChanged();
}
};
这些是我的 LoaderCallback
方法:
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
Loader<Cursor> loader = null;
switch (loaderId) {
case LOADER_ORDERS:
System.out.println("Create loader called");
loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);
break;
}
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (getActivity() == null) {
return;
}
if (data != null && !data.isClosed()) {
System.out.println("Finished loading orders, data not null");
switch (loader.getId()) {
case LOADER_ORDERS:
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
subscription = AndroidObservable
.bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
.subscribeOn(Schedulers.computation())
.unsubscribeOn(AndroidSchedulers.mainThread())
.subscribe(mObjectiveObserver);
System.out.println("I should be here, onLoadFinished");
break;
}
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
内容观察者代码如下:
class HomeOrdersContentObserver extends ContentObserver {
private int mLoaderId = 0;
public HomeOrdersContentObserver(Handler handler, int loaderId) {
super(handler);
mLoaderId = loaderId;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (getActivity() == null) {
return;
}
Bundle bundle = new Bundle();
//bundle.putString(FILTER_TXT, lastFilterQ);
restartLoader(mLoaderId, bundle);
}
}
public void restartLoader(int loaderId, Bundle args) {
getLoaderManager().restartLoader(loaderId, args, this);
}
我已将日志放在代码中的各个位置,并且它们会按应有的方式打印,除了这个 onNext
和 onCompleted
方法。我的实施中可能缺少什么想法吗?
解决方案
我发现上面的代码有一些问题。
第一:您实际上并没有在任何地方调用 onNext/onCompleted 。由于您正在尝试连接两个范例(Loader 和 Rx),因此您需要将 onNext 放在 onLoadFinished 中(如果您希望在没有数据时调用它,则使用 onError,但这将关闭订阅)和 onCompleted 中加载器重置
第二:您正在 onLoadFinished 中重做订阅,我认为您不希望这样做 - 为什么每次有新数据时您都想重新订阅?您应该在创建加载程序时执行此操作,并在销毁加载程序时取消订阅(onLoaderReset)。
这是一种可能的实现:
@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
Loader<Cursor> loader = null;
switch (loaderId) {
case LOADER_ORDERS:
System.out.println("Create loader called");
loader = new CursorLoader(OrderManagerApplication.getAppContext(), OrderManagerContract.Order.CONTENT_URI,
QueryOrder.PROJECTION_SIMPLE, null, null, OrderManagerContract.Order.DATE_SORT);
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
subscription = AndroidObservable
.bindFragment(this, DatabaseHelper.mainOrdersObservable(data))
.subscribeOn(Schedulers.computation())
.unsubscribeOn(AndroidSchedulers.mainThread())
.subscribe(mObjectiveObserver);
break;
}
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (getActivity() == null) {
return;
}
if (data != null && !data.isClosed()) {
System.out.println("Finished loading orders, data not null");
switch (loader.getId()) {
case LOADER_ORDERS:
mObjectiveObserver.onNext(data);
System.out.println("I should be here, onLoadFinished");
break;
}
} else {
mObjectiveObserver.onError("No data available");
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
if (subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
请记住,像这样的结构,如果没有数据,它实际上会关闭订阅(onError 就是这样做的),因此您将无法从加载器接收更多数据。如果您不希望这样,那么在上面的 onError 情况下,您实际上会使用 null 或 new ArrayList 调用 onNext,然后在观察者中处理它。
不隶属于 StackOverflow