我正在学习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()呼叫之前。

07-26 01:13