AndroidObservable从不在主线程上观察

AndroidObservable从不在主线程上观察,android,multithreading,rx-java,Android,Multithreading,Rx Java,我正在试验。我正在尝试一个简单的例子,在这个例子中,我试图在后台线程上卸载一个较长的操作,然后期望在主线程上返回并执行ui操作 我从EditTextonTextChangeListener(通过漂亮的ButterKnife注入)获取搜索文本,然后将其发送到一个长时间运行的操作\u searchForContacts(searchText),该操作返回联系人对象列表。然后,我通过在适配器上设置信息并通知数据集更改来更新视图 但是,我在尝试进行任何ui更新时遇到异常,因为我从来都不在主线程上 这是我

我正在试验。我正在尝试一个简单的例子,在这个例子中,我试图在后台线程上卸载一个较长的操作,然后期望在主线程上返回并执行ui操作

我从
EditText
onTextChangeListener
(通过漂亮的ButterKnife注入)获取搜索文本,然后将其发送到一个长时间运行的操作
\u searchForContacts(searchText)
,该操作返回联系人对象列表。然后,我通过在适配器上设置信息并通知数据集更改来更新视图

但是,我在尝试进行任何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();
    }
}
公共类MyTestFragment
扩展片段
实现观察器{
// ...
私人订阅_searchguestsubscription=Subscriptions.empty();
// ...
@凌驾
公共无效onDestroyView(){
super.onDestroyView();
_SearchGuestSubscription.Unsubscripte();
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
_适配器=新的ContactImportAdapter();
_adapter.setContacts(_searchForContacts(所有_CONTACTS));
_setAdapter(_adapter);
}
@凌驾
public void onNext(列出联系人搜索结果){
d(“我在主线程上->”+String.valueOf(Looper.myLooper()==Looper.getMainLooper());
_adapter.setContacts(contactSearchResults);
}
@凌驾
未完成的公共无效(){
_updateView();
}
@凌驾
公共无效申报人(可丢弃的e){
tember.e(e,“哎呀,出了点问题。”);
}
//ButterKnife~onTextChangeListener
@ContextChanged(R.id.search\u edit\u text)
无效onSearchContact(CharSequence searchChars){
_SearchGuestSubscription=AndroidObservable.bindFragment(此,
_searchGuestsObservable(searchChars.toString())
//下面这行似乎没有任何效果?
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.认购(本);
}
私有可观察_searchGuestsObservable(最终字符串searchText){
返回Observable.create(newobservable.OnSubscribe(){
@凌驾

public void call(Subscriber您的问题似乎是因为您在片段中直接调用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();
        }
    });
}
private Observable\u searchGuestsObservable(最终字符串searchText){
返回Observable.create(newobservable.OnSubscribe(){
@凌驾

public void call(SubscriberTry在另一个线程上运行您的意思是尝试在.io线程以外的线程上运行吗?我实际上也尝试了
Schedulers.newThread()
但这不起作用。如果我只坚持使用主线程,那么一切都会起作用,但我想这会使问题迎刃而解,因为我明确希望在非ui线程上运行该操作,然后回调到ui线程。没错!我喜欢指责糟糕的语法(Android不支持Java 8功能)但事实是我根本没有正确理解通话顺序。谢谢你,干杯!