android - 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()
我都可以看到它在主线程上运行。它绝对必须在另一个线程上。这怎么可能 ?
解决方案
问题在这里 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);
}
});
}
推荐阅读
- c++ - NULL 是有效的 FILE* 吗?
- python - 我应该在 Python 中有一个单独的导入文件吗?什么是最佳实践?
- kotlin - 如何在 Kotin 中使用 putextra()
- javascript - 仅在字符串 Javascript 中将搜索字符串与单词开头匹配
- javascript - 如何将 PHP 数组索引转换为 javascript 变量
- discord - Discord Python 重写 - 广播
- python - 给出大量数字时如何解决python应用程序无响应问题
- javascript - 为什么一段时间后 Cookie 没有变化?还是返回最后一个值?
- laravel - 如何返回到分页页面?
- xcode - 我可以在安装在外置硬盘中的 Xcode 中使用颤振吗?