Observable android 理解
Observable android understanding
我正在尝试了解观察者模式在 Android 中的工作原理。
我创建了这个方法来加载示例对象列表,将每个项目推送到订阅者并将其加载到 recyclerview 中。
我不明白为什么如果我加载 10 个项目一切正常,但如果我加载 100/1000 或通常更多的项目,recyclerView 是空的并且不会触发 onNext、onComplete。
private Observable<AppInfo> getAppList() {
return Observable.create(new Observable.OnSubscribe<AppInfo>() {
@Override
public void call(Subscriber<? super AppInfo> subscriber) {
for (int i = 0; i<10; i++){
AppInfo appInfo = new AppInfo(
"Test item "+i,
ContextCompat.getDrawable(getApplicationContext(), R.mipmap.ic_launcher),
i
);
subscriber.onNext(appInfo);
}
if (!subscriber.isUnsubscribed()) {
subscriber.onCompleted();
}
}
});
}
这就是我使用 Observable 的方式:
Observable<AppInfo> appInfoObserver = getAppList();
appInfoObserver
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<AppInfo>() {
@Override
public void onCompleted() {
Toast.makeText(getApplicationContext(), "App List Load Completed!", Toast.LENGTH_LONG).show();
}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(AppInfo appInfo) {
if(mAppInfoList != null){
mAppInfoList.add(appInfo);
adapter.notifyItemInserted(appInfo.getAppPosition());
}
}
});
感谢您的帮助和建议。
也许您的代码太重并且加载同步。尝试在一个新线程中加载你的代码,也许你可以使用 observeOn() (我不知道 rxjava 是如何工作的,但我的猜测是这个函数定义了事件发生的线程)。
您没有记录错误,因此如果出现任何问题您都不会知道(在这种情况下,您可能通过发送比请求更多的内容来强制 observeOn
操作员发送 MissingBackpressureException
).要清楚,在订阅者中:
public void onError(Throwable e) {
// log or display error here!!
}
如果可以,请不要使用 Observable.create
,因为您需要承受背压或将其与 .onBackpressureBuffer
结合使用。
例外情况是 Observable.create(new SyncOnSubscribe<T>(...))
是创建 Observable
的好方法,前提是您可以将来源想象成 iterator/enumeration。
要避免在您的示例中使用 Observable.create
,您可以这样做:
Observable
.range(0, 10)
.map(i -> new AppInfo(...))
或没有 lambda:
Observable
.range(0, 10)
.map(new Func1<Integer, AppInfo>() {
@Override
public AppInfo call(Integer n) {
return new AppInfo(...);
}
});
我正在尝试了解观察者模式在 Android 中的工作原理。
我创建了这个方法来加载示例对象列表,将每个项目推送到订阅者并将其加载到 recyclerview 中。
我不明白为什么如果我加载 10 个项目一切正常,但如果我加载 100/1000 或通常更多的项目,recyclerView 是空的并且不会触发 onNext、onComplete。
private Observable<AppInfo> getAppList() {
return Observable.create(new Observable.OnSubscribe<AppInfo>() {
@Override
public void call(Subscriber<? super AppInfo> subscriber) {
for (int i = 0; i<10; i++){
AppInfo appInfo = new AppInfo(
"Test item "+i,
ContextCompat.getDrawable(getApplicationContext(), R.mipmap.ic_launcher),
i
);
subscriber.onNext(appInfo);
}
if (!subscriber.isUnsubscribed()) {
subscriber.onCompleted();
}
}
});
}
这就是我使用 Observable 的方式:
Observable<AppInfo> appInfoObserver = getAppList();
appInfoObserver
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<AppInfo>() {
@Override
public void onCompleted() {
Toast.makeText(getApplicationContext(), "App List Load Completed!", Toast.LENGTH_LONG).show();
}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(AppInfo appInfo) {
if(mAppInfoList != null){
mAppInfoList.add(appInfo);
adapter.notifyItemInserted(appInfo.getAppPosition());
}
}
});
感谢您的帮助和建议。
也许您的代码太重并且加载同步。尝试在一个新线程中加载你的代码,也许你可以使用 observeOn() (我不知道 rxjava 是如何工作的,但我的猜测是这个函数定义了事件发生的线程)。
您没有记录错误,因此如果出现任何问题您都不会知道(在这种情况下,您可能通过发送比请求更多的内容来强制 observeOn
操作员发送 MissingBackpressureException
).要清楚,在订阅者中:
public void onError(Throwable e) {
// log or display error here!!
}
如果可以,请不要使用 Observable.create
,因为您需要承受背压或将其与 .onBackpressureBuffer
结合使用。
例外情况是 Observable.create(new SyncOnSubscribe<T>(...))
是创建 Observable
的好方法,前提是您可以将来源想象成 iterator/enumeration。
要避免在您的示例中使用 Observable.create
,您可以这样做:
Observable
.range(0, 10)
.map(i -> new AppInfo(...))
或没有 lambda:
Observable
.range(0, 10)
.map(new Func1<Integer, AppInfo>() {
@Override
public AppInfo call(Integer n) {
return new AppInfo(...);
}
});