我正在学习RxAndroid,并从我的项目中的一个非常简单的示例开始。即以可观察的方式获取用户个人资料图片网址响应。
下面是获取字符串URL值的代码,我使用Picasso加载图像URL。当我使用runonUiThread加载图像时,代码可以正常工作,但是当我不使用图像时使用它会引发错误。它说方法调用应该在主线程中。
doOnNext和doOnCompleted是否总是在后台线程上运行吗?
picUrlSubscription = getUrlAsObservable()
.map(responseBodyResponse -> {
Log.d(TAG, "map ");
try {
if (responseBodyResponse.isSuccessful()) {
observableStr = responseBodyResponse.body().string();
return observableStr;
} else {
observableStr = "Bad_url";
return observableStr;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
})
.doOnNext(s -> {
Log.d(TAG, "next ");
try {
if (s != null && !s.equalsIgnoreCase("Bad_url")) {
observableStr = new JSONObject(s).getString("url");
} else
runOnUiThread(() -> profileCircle.setImageResource(R.drawable.profil));
} catch (JSONException e) {
e.printStackTrace();
runOnUiThread(() -> profileCircle.setImageResource(R.drawable.profil));
}
})
.doOnCompleted(() -> {
Log.d(TAG, "completed ");
runOnUiThread(() -> Picasso.with(this).load(observableStr).into(profileCircle));
})
.onErrorReturn(throwable -> {
Log.d(TAG, "error "+ throwable.getMessage());
observableStr = "bad_url";
runOnUiThread(() -> profileCircle.setImageResource(R.drawable.profil));
return observableStr;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
最佳答案
不,doOnNext()
和doOnCompleted()
在指定的任何线程上运行以通知其观察者。如果未指定任何线程,则它们将在可观察到的线程上运行。
由于您指定了subscribeOn(Schedulers.io())
,因此可观察对象将在io
线程上运行。根据documentation; subscribeOn()
运算符指定可观察对象将在哪个线程上运行,而不管其出现在链中的哪个位置,这与observeOn()
运算符不同:
另一方面,ObserveOn
影响Observable
将在下面显示该运算符的位置使用。
因此,将observeOn()
呼叫放在doOnNext()
和doOnCompleted()
呼叫之前。