首页 > 解决方案 > rxJava2 Single.Just() 总是在主线程中执行。如何让它在另一个线程上执行?

问题描述

在这段代码摘录中,我试图处理一堆数据,但它不能在 UI 线程上,否则体验可能是 ANR。我认为这很容易用 rxJava2 完成,但是,数据处理总是在主线程上运行。

数据加载在“演示者”中触发,如下所示:

void loadHistoricalDataFromFile(String filename){
    view.showProgressDialog();
    addDisposable(
            model.loadHistoricalDataObservable(filename)
                    .subscribeOn(rxSchedulers.runOnBackground())
                    .observeOn(rxSchedulers.mainThread())
                    .subscribe(loadedSuccessfully -> {
                        view.hideProgressDialog();
                        if (loadedSuccessfully){
                            view.showSnackBar(R.string.simulator_loaded_data_success, LENGTH_SHORT);
                        } else {
                            view.showSnackBar(R.string.simulator_loaded_data_fail, LENGTH_INDEFINITE);
                        }
                    }));
}

如你所见,我用过.subscribeOn(rxSchedulers.runOnBackground())

rxSchedulers.runOnBackground()实现如下:

public class AppRxSchedulers implements RxSchedulers {


    public static Executor backgroundExecutor = Executors.newCachedThreadPool();
    public static Scheduler BACKGROUND_SCHEDULERS = Schedulers.from(backgroundExecutor);
    public static Executor internetExecutor = Executors.newCachedThreadPool();
    public static Scheduler INTERNET_SCHEDULERS = Schedulers.from(internetExecutor);
    public static Executor singleExecutor = Executors.newSingleThreadExecutor();
    public static Scheduler SINGLE_SCHEDULERS = Schedulers.from(singleExecutor);

    @Override
    public Scheduler runOnBackground() {
        return BACKGROUND_SCHEDULERS;
    }

    @Override
    public Scheduler io() {
        return Schedulers.io();
    }

    @Override
    public Scheduler compute() {
        return Schedulers.computation();
    }

    @Override
    public Scheduler mainThread() {
        return AndroidSchedulers.mainThread();
    }

    @Override
    public Scheduler internet() {
        return INTERNET_SCHEDULERS;
    }

    @Override
    public Scheduler single() {
        return SINGLE_SCHEDULERS;
    }
}

Single.Just() 实现如下

Single<Boolean> loadHistoricalDataObservable(String filename){
    return Single.just(loadHistoricalData(filename));
}

private Boolean loadHistoricalData(String filename){
    boolean successful = false;
    String json = FileUtils.readFileAsStringFromExtRam(filename);
    if (json.length() > 0) {
        Gson gson = new Gson();
        historicPriceList = null;
        historicPriceList = gson.fromJson(json, new TypeToken<List<HistoricPrice>>(){}.getType());
        successful = true;
        Timber.d("Successfully loaded file - recreated %d records", historicPriceList.size());
    } else {
        Timber.d("Failed to load file");
    }

    return successful;
}

主要问题是,每当我在其中遇到断点时,loadHistoricalData()我都可以看到它在主线程上运行。它绝对必须在另一个线程上。这怎么可能 ?

标签: androidrx-java2

解决方案


问题在这里 Single.just(loadHistoricalData(filename));

您立即调用该函数,然后将其结果传递给 Single.just(); 您需要将其更改为以下内容:

Single.fromCallable(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                return loadHistoricalData(filename);
            }
        });

所以它看起来像这样:

Single<Boolean> loadHistoricalDataObservable(String filename){
    return Single.fromCallable(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    return loadHistoricalData(filename);
                }
            });
}

推荐阅读