Observable仍然在UI线程上运行

时间:2017-10-04 17:06:35

标签: java android rx-java rx-android

我遇到在新线程上运行RxJava observable的问题。我试图在Scheduler.io()上运行压缩数据库查询,但无论如何都会阻止UI线程。不知道为什么。

DB代码:

public Observable<List<T>> searchModelsInView(View view, final Collection<String> searchTerms,
        KeyMatchLevel keyMatchLevel, int queryLim) {
    return Observable.just(
            searchModelsTask(view, new HashSet<>(searchTerms), keyMatchLevel, queryLim));
}

这是发生压缩的代码:

 public Observable<Set<Airport>> getSearchResultsForAll(String term, int queryLim) {
    List<String> terms = CollectionsUtil.asArrayList(term);
    Observable<List<Airport>> macObservable = onNewThread(
            searchModelsInView(getMacView(), terms,
                    KeyMatchLevel.PREFIXED, queryLim));
    Observable<List<Airport>> nameObservable = onNewThread(
            searchModelsInView(getNameView(), terms,
                    KeyMatchLevel.PREFIXED, queryLim));
    Observable<List<Airport>> codeObservable = onNewThread(
            searchModelsInView(getCodeView(), terms,
                    KeyMatchLevel.PREFIXED, NONE));
    Observable<List<Airport>> regionObservable = onNewThread(
            searchModelsInView(getCityView(), terms,
                    KeyMatchLevel.PREFIXED, NONE));

    ;
    return Observable.zip(macObservable, nameObservable, codeObservable, regionObservable,
            (macList, nameList, codeList, regionList) -> {

                Set<Airport> resultSet = new LinkedHashSet<Airport>();

                Airport mac = macList.get(0);

                if (term.length() > CODE_LEN) {
                    if (lowerCase(mac.getCity()).contains(lowerCase(term))) {
                        handleMACFound(resultSet, mac, regionList);
                        return resultSet;
                    }
                    resultSet.addAll(nameList);
                    resultSet.addAll(regionList);
                    return resultSet;
                }


                boolean macFound = StringUtil.isEquals(lowerCase(term),
                        lowerCase(mac.getCode()));

                if (macFound) {
                    handleMACFound(resultSet, mac, codeList);
                    return resultSet;
                }

                resultSet.addAll(codeList);
                resultSet.addAll(nameList);
                resultSet.addAll(regionList);

                return resultSet;
            });
}

private Observable<List<Airport>> onNewThread(Observable<List<Airport>> observable) {
    return observable.subscribeOn(Schedulers.io());
}

这就是它的名字:

public void searchKey(String searchTerms, Airport... excluding) {
    TBDataBase.getAirportDB()
            .getSearchResultsForAll(searchTerms, MAX_AIRPORT_SEARCHED)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(airports -> {
                setResults(airports, excluding);
                listener.onRegularAirportSearch();
                listener.onSearchPerformed();
            });


}

它似乎应该在Scheduler.io()上运行,但它会阻止主线程,所以它不会。

1 个答案:

答案 0 :(得分:2)

看起来问题出在你的searchModelsTask中:

public Observable<List<T>> searchModelsInView(View view, final Collection<String> searchTerms,
        KeyMatchLevel keyMatchLevel, int queryLim) {
    return Observable.just(
            searchModelsTask(view, new HashSet<>(searchTerms), keyMatchLevel, queryLim));
}

Observable.just希望你已经拥有了这个价值。所以它甚至在创建observable之前执行searchModelsTask。因此,您尝试将其放在I / O调度程序上并不重要。尝试使用内部延迟:

public Observable<List<T>> searchModelsInView(View view, final Collection<String> searchTerms,
        KeyMatchLevel keyMatchLevel, int queryLim) {
    return Observable.defer(() -> Observable.just(
            searchModelsTask(view, new HashSet<>(searchTerms), keyMatchLevel, queryLim)));
}

public Observable<List<T>> searchModelsInView(View view, final Collection<String> searchTerms,
            KeyMatchLevel keyMatchLevel, int queryLim) {

return Observable.defer(new Func0<Observable<List<T>>>(){

        @Override
        public Observable<List<T>> call() {
            return Observable.just(
                    searchModelsTask(view, new HashSet<>(searchTerms), keyMatchLevel, queryLim));
        }
    });
}

您也可以考虑使用Observable.callable而不是延迟。