RxJava中的AsyncTask

时间:2015-11-29 06:46:09

标签: android rx-java

我无法理解如何在RxJava中翻译简单的AsyncTask。举个例子:

private class Sync extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {
              String proxy_arr = "";
                    try {
                        Document jsoup_proxy = Jsoup.connect(Constants.SITE_PROXY_LIST)
                                .userAgent(Constants.USER_AGENT)
                                .ignoreContentType(true)
                                .ignoreHttpErrors(true)
                                .timeout(Constants.USER_TIMEOUT)
                                .get();

                        if (jsoup_proxy != null) proxy_arr = jsoup_proxy.text().trim();
                    } catch (IOException e) {
                        new DebugLog(getActivity(), "News", "Sync PROXY", Log.getStackTraceString(e));
                    }
              return proxy_arr;
    }

    @Override
    protected void onPostExecute(String result) {
        if (result.equals("err_internet")){
            func.toastMessage(R.string.toast_err_nointernet, "", "alert");
        }

        reloadAdapter();
    }
}

因为它可以在相同的工作条件下翻译RxJava? 谢谢!

3 个答案:

答案 0 :(得分:3)

当您将功能转换为反应时,请记住您应该定义

  • onNext
  • onError
  • onCompleted

&#34;事件&#34;

实际上rx与数据序列配合得很好,但当然你可以创建一个只有一个发射项的数据序列。 所以要修改你的反应方法我首先要说你应该分担责任。

在存储库类中的某个位置,或者根据您的体系结构命名它,您只需创建它:

    public Observable<String> getProxyAsync() {
        return Observable.create(subscriber -> {
            String proxy_arr = "";
            try {
                Document jsoup_proxy = Jsoup.connect(Constants.SITE_PROXY_LIST)
                    .userAgent(Constants.USER_AGENT)
                    .ignoreContentType(true)
                    .ignoreHttpErrors(true)
                    .timeout(Constants.USER_TIMEOUT)
                    .get();

                if (jsoup_proxy != null) proxy_arr = jsoup_proxy.text().trim();

                subscriber.onNext(proxy_arr);
            } catch (IOException e) {
                subscriber.onError(e);
            } finally {
                subscriber.onCompleted();
            }
        });
    }

之后,在活动附近,只需订阅此方法:

public void myPreciousMethod() {
    myCustomRepo.getProxyAsync()
        .subscribeOn(Schedulers.newThread())
        .subscribe(result -> {
            runOnUiThread(() -> {
                if (result.equals("err_internet")) {
                    func.toastMessage(R.string.toast_err_nointernet, "", "alert");
                }
            });
        }, throwable -> {
            // some exception happened emmited by your code, handle it well
            new DebugLog(getActivity(), "News", "Sync PROXY", Log.getStackTraceString(e));
        }, () -> {
            // onCompleted:
            runOnUiThread(() -> reloadAdapter());
        });
}

我建议使用.runOnUiThread()(在您的活动或任何其他与rx相关的视图操作中)以避免背压,但这实际上取决于发射数据的数量和频率。 (您也可以使用.observeOn().subscribeOn())为了更清晰的代码,强烈建议使用retrolambda。

答案 1 :(得分:3)

您应该使用Observable.create或更好Observable.defer()(在RxJava 1.0.15中引入),而不是使用Observable.fromCallable - 因为这些方法将确保合适的可观察合同并保存你可以从手工创造可观察的错误中引入一些错误。

此外,您应该使用为此目的而创建的runOnUiThread,而不是按照上述其中一个答案中的建议使用AndroidSchedulers.mainThread()。只需使用提供它的RxAndroid库。

我建议采用以下解决方案:

public Observable<String> getJsoupProxy() {
  return Observable.fromCallable(() -> {
      try {
        Document jsoup_proxy = Jsoup.connect(Constants.SITE_PROXY_LIST)
          .userAgent(Constants.USER_AGENT)
          .ignoreContentType(true)
          .ignoreHttpErrors(true)
          .timeout(Constants.USER_TIMEOUT)
          .get();

        return jsoup_proxy != null ? jsoup_proxy.text().trim() : "";
      } catch (IOException e) {
        // just rethrow as RuntimeException to be caught in subscriber's onError
        throw new RuntimeException(e);
      }
    });
}

getJsoupProxy()
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread()) // this scheduler is exported by RxAndroid library
  .subscribe(
     proxy -> {
       if(proxy.equals("err_internet")) {
         // toast
       }
       reloadAdapter();
     },
     error -> new DebugLog(getActivity(), "News", "Sync PROXY", Log.getStackTraceString(error)));

答案 2 :(得分:1)

这是一种做法。如果需要,你可以放弃推迟。

        Observable.defer(new Func0<Observable<String>>() {
                @Override
                public Observable<String> call() {
                    return Observable.create(new Observable.OnSubscribe<String>() {
                        @Override
                        public void call(Subscriber<? super String> subscriber) {
                            String proxy_arr = "";
                            try {
                                Document jsoup_proxy = Jsoup.connect(Constants.SITE_PROXY_LIST)
                                        .userAgent(Constants.USER_AGENT)
                                        .ignoreContentType(true)
                                        .ignoreHttpErrors(true)
                                        .timeout(Constants.USER_TIMEOUT)
                                        .get();

                                if (jsoup_proxy != null) proxy_arr = jsoup_proxy.text().trim();
                            } catch (IOException e) {
                                new DebugLog(getActivity(), "News", "Sync PROXY", Log.getStackTraceString(e));
                            }
                            if (!subscriber.isUnsubscribed()) {
                                subscriber.onNext(proxy_arr);
                            }
                        }
                    })
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<String>() {
                @Override
                public void call(String result) {
                    if (result.equals("err_internet")){
                        func.toastMessage(R.string.toast_err_nointernet, "", "alert");
                    }
                    reloadAdapter();
                }
            });