- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在试验 RxJava for Android .我正在尝试一个简单的示例,我正在尝试卸载后台线程上的较长操作,然后期望返回主线程并执行 ui 操作。
我从 EditText
onTextChangeListener
获取搜索文本(通过漂亮的 ButterKnife 注入(inject)),然后将其发送到长时间运行的操作 _searchForContacts( searchText)
返回联系人对象列表。然后,我通过在我的适配器上设置信息并通知数据集更改来继续更新我的 View 。
但是,我在尝试进行任何 ui 更新时遇到异常,因为我从不在主线程上。
这是我的代码:
public class MyTestFragment
extends Fragment
implements Observer<List<Contact>> {
// ...
private Subscription _searchGuestsSubscription = Subscriptions.empty();
// ...
@Override
public void onDestroyView() {
super.onDestroyView();
_searchGuestsSubscription.unsubscribe();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
_adapter = new ContactImportAdapter();
_adapter.setContacts(_searchForContacts(ALL_CONTACTS));
_listView.setAdapter(_adapter);
}
@Override
public void onNext(List<Contact> contactSearchResults) {
Timber.d("I'm on the main thread -> " + String.valueOf(Looper.myLooper() == Looper.getMainLooper()));
_adapter.setContacts(contactSearchResults);
}
@Override
public void onCompleted() {
_updateView();
}
@Override
public void onError(Throwable e) {
Timber.e(e, "Oops something went wrong.");
}
// ButterKnife ~ onTextChangeListener
@OnTextChanged(R.id.search_edit_text)
void onSearchContact(CharSequence searchChars) {
_searchGuestsSubscription = AndroidObservable.bindFragment(this,
_searchGuestsObservable(searchChars.toString()))
// The below line doesn't seem to have any effect?
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this);
}
private Observable<List<Contact>> _searchGuestsObservable(final String searchText) {
return Observable.create(new Observable.OnSubscribe<List<Contact>>() {
@Override
public void call(Subscriber<? super List<Contact>> searchResultObserver) {
// do the search
List<Contact> contactSearchResults = _searchForContacts(searchText);
onNext(contactSearchResults);
onCompleted();
}
});
}
private void _updateView() {
_adapter.notifyDataSetChanged();
}
}
它表示 onNext
总是在后台线程上调用。我得到了通常的 IllegalStateException: The current thread must have a looper!
异常。日志语句还表明我不在 onNext
中的主线程上。
什么给了?
最佳答案
您的问题似乎是因为您直接在 Fragment 中调用 onNext 而不是在订阅者上调用 onNext。
像这样更改您的代码。
private Observable<List<Contact>> _searchGuestsObservable(final String searchText) {
return Observable.create(new Observable.OnSubscribe<List<Contact>>() {
@Override
public void call(Subscriber<? super List<Contact>> searchResultObserver) {
// do the search
List<Contact> contactSearchResults = _searchForContacts(searchText);
searchResultObserver.onNext(contactSearchResults);
searchResultObserver.onCompleted();
}
});
}
当您的 Observable.OnSubscribe<List<Contact>>()
由于subscribeOn(Schedulers.io())
,您实际上在后台线程上执行了并且您自己调用 Fragment 的 onNext,这就是您获得该异常的原因。
关于AndroidObservable 从不在主线程上观察,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24900987/
有人可以向我澄清主线 DHT 规范中的声明吗? Upon inserting the first node into its routing table and when starting up th
我正在尝试使用 USB 小工具驱动程序使嵌入式设备作为 MTP 设备工作。 我知道 Android 从大容量存储设备切换到 MTP 设备已经有一段时间了,并且找到了 source code for M
我是一名优秀的程序员,十分优秀!