title: RxAndroid and Retrofit: Unable to create call adapter for io.reactivex.Observable<retrofit2.Response<okhttp3.ResponseBody>>
body: <p>I am trying use rxJava, rxAndroid, Retrofit2, and OkHTTP3 to download a file from a URL endpoint. My code is unable to create the call adapter for an "Observable&lt; retrofit2.Response&lt; okhttp3.ResponseBody>>". These methods are new to me so I believe I'm missing an important concept here. Any direction or points is greatly appreciated.</p>
  
  <blockquote>
    <p>FATAL EXCEPTION: main
    Process: com.example.khe11e.rxdownloadfile, PID: 14130
    java.lang.IllegalArgumentException: Unable to create call adapter for io.reactivex.Observable>
       for method RetrofitInterface.downloadFileByUrlRx
       at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:720)
       at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:234)
       at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:160)
       at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
       at retrofit2.Retrofit$1.invoke(Retrofit.java:145)
       at java.lang.reflect.Proxy.invoke(Proxy.java:393)
       at $Proxy0.downloadFileByUrlRx(Unknown Source)
       at com.example.khe11e.rxdownloadfile.MainActivity.downloadImage(MainActivity.java:46)
       at com.example.khe11e.rxdownloadfile.MainActivity$1.onClick(MainActivity.java:39)
       at android.view.View.performClick(View.java:5207)
       at android.view.View$PerformClick.run(View.java:21168)
       at android.os.Handler.handleCallback(Handler.java:746)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5491)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for io.reactivex.Observable>.
     Tried:
      * retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
      * retrofit2.ExecutorCallAdapterFactory
       at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:237)
       at retrofit2.Retrofit.callAdapter(Retrofit.java:201)
       at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:232)
        ... 16 more</p>
  </blockquote>
  
  <p>build.gradle:</p>
  
  <pre><code>compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
  compile 'io.reactivex.rxjava2:rxjava:2.0.4'
  compile 'com.squareup.retrofit2:retrofit:2.1.0'
  compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
  </code></pre>
  
  <p>RetrofitInterface.java:</p>
  
  <pre><code>package com.example.khe11e.rxdownloadfile;
  import io.reactivex.Observable;
  import okhttp3.ResponseBody;
  import retrofit2.Call;
  import retrofit2.Response;
  import retrofit2.http.GET;
  import retrofit2.http.Streaming;
  import retrofit2.http.Url;
  
  public interface RetrofitInterface {
      // Retrofit 2 GET request for rxjava
      @Streaming
      @GET
      Observable&lt;Response&lt;ResponseBody&gt;&gt; downloadFileByUrlRx(@Url String fileUrl);
  }
  </code></pre>
  
  <p>MainActivity.java:</p>
  
  <pre><code>package com.example.khe11e.rxdownloadfile;
  
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.View;
  import android.widget.Button;
  import java.io.File;
  import io.reactivex.Observable;
  import io.reactivex.ObservableEmitter;
  import io.reactivex.ObservableOnSubscribe;
  import io.reactivex.Observer;
  import io.reactivex.android.schedulers.AndroidSchedulers;
  import io.reactivex.disposables.Disposable;
  import io.reactivex.functions.Function;
  import io.reactivex.schedulers.Schedulers;
  import okhttp3.OkHttpClient;
  import okhttp3.ResponseBody;
  import okio.BufferedSink;
  import okio.Okio;
  import retrofit2.Response;
  import retrofit2.Retrofit;
  import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
  
  public class MainActivity extends AppCompatActivity {
  
  Button downloadImgBtn;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      downloadImgBtn = (Button) findViewById(R.id.downloadImgBtn);
      downloadImgBtn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              downloadImage();
          }
      });
  }
  
  public void downloadImage(){
      RetrofitInterface downloadService = createService(RetrofitInterface.class, "https://www.nasa.gov/");
      downloadService.downloadFileByUrlRx("sites/default/files/iss_1.jpg")
              .flatMap(processResponse())
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe(handleResult());
  }
  
  public &lt;T&gt; T createService(Class&lt;T&gt; serviceClass, String baseUrl){
      Retrofit retrofit = new Retrofit.Builder()
              .baseUrl(baseUrl)
              .client(new OkHttpClient.Builder().build())
              .addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
      return retrofit.create(serviceClass);
  }
  
  public Function&lt;Response&lt;ResponseBody&gt;, Observable&lt;File&gt;&gt; processResponse(){
      return new Function&lt;Response&lt;ResponseBody&gt;, Observable&lt;File&gt;&gt;() {
          @Override
          public Observable&lt;File&gt; apply(Response&lt;ResponseBody&gt; responseBodyResponse) throws Exception {
              return saveToDiskRx(responseBodyResponse);
          }
      };
  }
  
  private Observable&lt;File&gt; saveToDiskRx(final Response&lt;ResponseBody&gt; response){
      return Observable.create(new ObservableOnSubscribe&lt;File&gt;() {
          @Override
          public void subscribe(ObservableEmitter&lt;File&gt; subscriber) throws Exception {
              String header = response.headers().get("Content-Disposition");
              String filename = header.replace("attachment; filename=", "");
              new File("/data/data/" + getPackageName() + "/images").mkdir();
              File destinationFile = new File("/data/data/" + getPackageName() + "/images/" + filename);
  
              BufferedSink bufferedSink = Okio.buffer(Okio.sink(destinationFile));
              bufferedSink.writeAll(response.body().source());
              bufferedSink.close();
  
              subscriber.onNext(destinationFile);
              subscriber.onComplete();
          }
      });
  }
  
  private Observer&lt;File&gt; handleResult(){
      return new Observer&lt;File&gt;() {
          @Override
          public void onSubscribe(Disposable d) {
              Log.d("OnSubscribe", "OnSubscribe");
          }
  
          @Override
          public void onNext(File file) {
              Log.d("OnNext", "File downloaded to " + file.getAbsolutePath());
          }
  
          @Override
          public void onError(Throwable e) {
              e.printStackTrace();
              Log.d("Error", "Error " + e.getMessage());
          }
  
          @Override
          public void onComplete() {
              Log.d("OnComplete", "onCompleted");
          }
      };
  }
  }
  </code></pre>
  
  <p>I've tried adding Call as mentioned <a href="https://stackoverflow.com/questions/32269064/unable-to-create-call-adapter-for-class-example-simple">here</a> so it looks like:</p>
  
  <pre><code>Call&lt;Observable&lt;Response&lt;ResponseBody&gt;&gt;&gt; downloadFileByUrlRx(@Url String fileUrl);
  </code></pre>
  
  <p>however this causes issues with the flatMap function as it cannot find symbol method flatMap(Function&lt; Response&lt; ResponseBody>,Observable&lt; File>>).</p>