Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用RxJava和Okhttp_Java_Android_Rx Java_Okhttp - Fatal编程技术网

使用RxJava和Okhttp

使用RxJava和Okhttp,java,android,rx-java,okhttp,Java,Android,Rx Java,Okhttp,我想在另一个线程(如IO线程)中使用okhttp请求url,并在Android主线程中获得响应,但我不知道如何创建可观察的首先将RxAndroid添加到依赖项中,然后像这样创建可观察的: Subscription subscription = Observable.create(new Observable.OnSubscribe<Response>() { OkHttpClient client = new OkHttpClient();

我想在另一个线程(如IO线程)中使用okhttp请求url,并在Android主线程中获得
响应
,但我不知道如何创建
可观察的
首先将
RxAndroid
添加到依赖项中,然后像这样创建
可观察的

 Subscription subscription =   Observable.create(new Observable.OnSubscribe<Response>() {
        OkHttpClient client = new OkHttpClient();
          @Override
          public void call(Subscriber<? super Response> subscriber) {
            try {
              Response response = client.newCall(new Request.Builder().url("your url").build()).execute();
              if (response.isSuccessful()) {
                  if(!subscriber.isUnsubscribed()){
                     subscriber.onNext(response);
                  }
                  subscriber.onCompleted();
              } else if (!response.isSuccessful() && !subscriber.isUnsubscribed()) {
                  subscriber.onError(new Exception("error"));
                }
            } catch (IOException e) {
              if (!subscriber.isUnsubscribed()) {
                  subscriber.onError(e);
              }
            }
          }
        })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<Response>() {
              @Override
              public void onCompleted() {

              }

              @Override
              public void onError(Throwable e) {

              }

              @Override
              public void onNext(Response response) {

              }
            });

使用
Observable.defer()
比使用
Observable.create()
更简单、更安全:

final-OkHttpClient=new-OkHttpClient();
可观察的延迟(新的Func0(){
@覆盖公共可观察调用(){
试一试{
Response Response=client.newCall(newrequest.Builder().url(“您的url”).build()).execute();
返回可观察的。公正(响应);
}捕获(IOE异常){
返回可观测误差(e);
}
}
});
这样就可以为您处理退订和背压。这里是关于
create()
defer()


如果您希望使用
Observable.create()
路线,那么它应该更像是在到处都是
isUnsubscribed()
调用的情况下。我相信这仍然不能解决背压问题。

我意识到这篇文章有点陈旧,但现在有了一种新的更方便的方法

Observable.fromCallable {
        client.newCall(Request.Builder().url("your url").build()).execute()
    }

更多信息:

我参加讨论迟到了,但是,如果出于某种原因代码需要流式传输响应正文,那么
延迟
从可调用的
将不会这样做。相反,可以使用
操作符使用

Single.using(() -> okHttpClient.newCall(okRequest).execute(), // 1
             response -> { // 2
                 ...

                 return Single.just((Consumer<OutputStream>) fileOutput -> {
                     try (InputStream upstreamResponseStream = response.body().byteStream();
                          OutputStream fileOutput = responseBodyOutput) {
                         ByteStreams.copy(upstreamResponseStream, output);
                     }
                 });
             },
             Response::close, // 3
             false) // 4
      .subscribeOn(Schedulers.io()) // 5
      .subscribe(copier -> copier.accept(...), // 6
                 throwable -> ...); // 7
Single.using(()->okHttpClient.newCall(okRequest.execute(),//1
响应->{//2
...
返回单个.just((使用者)文件输出->{
try(InputStream upstreamResponseStream=response.body().byteStream();
OutputStream文件输出=responseBodyOutput){
复制(上游响应流,输出);
}
});
},
响应::关闭,//3
假)//4
.subscribeOn(Schedulers.io())//5
.subscribe(copier->copier.accept(…),//6
可丢弃->…);//7.
  • 第一个lambda在订阅后执行响应
  • 第二个lambda创建可观察类型,这里使用
    Single.just(…)
  • 第三个lambda处理响应。使用
    defer
    可以使用try With resources样式
  • eager
    切换设置为
    false
    ,以便在终端事件之后,即在执行订阅消费者之后调用处理器
  • 当然,让这件事发生在另一个线程池上
  • 这是将消耗响应体的lambda。如果未将
    eager
    设置为
    false
    ,代码将引发IOException,原因为“closed”,因为在输入此lambda之前响应已关闭
  • onError
    lambda应该处理异常,尤其是
    IOException
    不能再使用
    操作符捕获的异常,因为使用
    延迟的try/catch是可能的

  • Okhttp3带有RxSingle后台API调用

         Disposable disposables = Single.fromCallable(() -> {
            Log.e(TAG, "clearData: Thread[" + Thread.currentThread().getName() + "]");
            OkHttpClient client = Util.getHttpClient();
            Request request = new Request.Builder()
                    .addHeader("Authorization", "Bearer " + Util.getUserToken())
                    .url(BuildConfig.BASE_URL + ApiConstants.DELETE_FEEDS)
                    .build();
    
            Response response = client.newCall(request).execute();
            if(response.isSuccessful()) {
               ...
               return ; // Any  type
            } else {
               return ; // Any type        
            }
        }).subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe((result) -> {
               Log.d(TAG, "api() completed");
          });
    
    
        compositeDisposable.add(disposables);
    

    除了Saeed接受的答案外,您还需要取消订阅以避免内存泄漏。来源:通过@Trilarion,您的链接似乎重定向到此页面(递归!),此解决方案不处理取消订阅或背压。我自己也不太清楚该如何处理,一般的建议是,现在我已经注意到情况比这更糟。它也会断裂。如果请求不成功,它将发出
    onNext
    onComplete
    ,然后才发出
    onError
    。您应该只发出
    onComplete
    onError
    ,但决不能同时发出两者。这可以通过多种方式很容易地解决。但这是一个完美的例子,说明了为什么编写自己的
    create()
    很困难,以及为什么避免它更安全。不!在RxJava 1.0中,如果想要创建一个可观察的对象,那么Observable.create几乎总是错误的。使用Observable.defer,就像另一个答案建议的那样。你能澄清一下代码吗?
    请求之前缺少一个
    new
    ,之后它抛出一个错误这不是Java,而是KotlinOps。。。错过了,对不起,您使用了什么版本的rxjava/okhttp来实现这一点?newCall.execute()返回一个不可调用的响应对象?请注意在。。。您将遇到一个非常常见的错误-UndeliverableException。请记住,如果您在http调用完成之前关闭订阅,它将崩溃。@f.khantsis那么如何避免这种情况,请使用try catch包装http调用如果这样做,您将丢失异常。我刚刚创建了一个
    maybefromunsafectallable
    调用,它模仿MaybeFromCallable,但在订阅关闭后函数抛出异常时不会抛出异常。同上,不可观察、不可感染等。。
    Single.using(() -> okHttpClient.newCall(okRequest).execute(), // 1
                 response -> { // 2
                     ...
    
                     return Single.just((Consumer<OutputStream>) fileOutput -> {
                         try (InputStream upstreamResponseStream = response.body().byteStream();
                              OutputStream fileOutput = responseBodyOutput) {
                             ByteStreams.copy(upstreamResponseStream, output);
                         }
                     });
                 },
                 Response::close, // 3
                 false) // 4
          .subscribeOn(Schedulers.io()) // 5
          .subscribe(copier -> copier.accept(...), // 6
                     throwable -> ...); // 7
    
         Disposable disposables = Single.fromCallable(() -> {
            Log.e(TAG, "clearData: Thread[" + Thread.currentThread().getName() + "]");
            OkHttpClient client = Util.getHttpClient();
            Request request = new Request.Builder()
                    .addHeader("Authorization", "Bearer " + Util.getUserToken())
                    .url(BuildConfig.BASE_URL + ApiConstants.DELETE_FEEDS)
                    .build();
    
            Response response = client.newCall(request).execute();
            if(response.isSuccessful()) {
               ...
               return ; // Any  type
            } else {
               return ; // Any type        
            }
        }).subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe((result) -> {
               Log.d(TAG, "api() completed");
          });
    
    
        compositeDisposable.add(disposables);