2017-02-05 9 views
6

rxJava、rxAndroid、Retrofit2、およびOkHTTP3を使用してURLエンドポイントからファイルをダウンロードしようとしています。私のコードは、 "Observable < retrofit2.Response < okhttp3.ResponseBody >>"のコールアダプタを作成できません。これらの方法は私には新しいものなので、ここでは重要な概念が欠けていると思います。どんな方向やポイントにも大変感謝しています。RxAndroidとRetrofit:io.reactivex.Observableのコールアダプターを作成できません。<retrofit2.Response <okhttp3.ResponseBody>

致命的な例外:メイン プロセス:com.example.khe11e.rxdownloadfile、PID:14130 java.lang.IllegalArgumentExceptionが:io.reactivex.Observableのコールアダプタを作成できません> 方法RetrofitInterface.downloadFileByUrlRx retrofit2でretrofit2.ServiceMethod $ Builder.buildでretrofit2.ServiceMethod $ Builder.createCallAdapterでretrofit2.ServiceMethod $ Builder.methodError(ServiceMethod.java:720) (ServiceMethod.java:234) (ServiceMethod.java:160) で.Retrofit.loadServiceMethod(Retrofit.java:166) at retrofit2.Retrofit $ 1.invoke(Retrofit.java:145) at java.lang.reflect.Proxy.invoke(Proxy.java:393) $ Proxy0.downloadFileByUrlRx(不明なソース) at com.example.khe11e.rxdownloadfile.MainActivity.downloadImage(MainActivity.java:46) at com.example.khe11e.rxdownloadfile.MainActivity $ 1.onClick(MainActivity.java:39) android.view.View.performClick(View.java:5207) android.view.View $ PerformClick.run(View.java :21168)android.os.Handler.handleCallback(Handler.java:746)の とandroid.os.Handler.dispatchMessage(Handler.java:95) とandroid.os.Looper.loop(Looper.java:148) ) android.app.ActivityThread.main(ActivityThread.java:5491) at java.lang.reflect.Method.invoke(ネイティブメソッド) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 原因:java.lang。 IllegalArgumentException:io.reactivex.Observable>の呼び出しアダプタを見つけることができませんでした。 しようとしました: * retrofit2.adapter.rxjava.RxJavaCallAdapterFactory * retrofit2.ExecutorCallAdapterFactory retrofit2.Retrofit.nextCallAdapter(Retrofit.java:237)retrofit2.Retrofit.callAdapter(Retrofit.java:201)で で retrofit2.ServiceMethodで$ Builder.createCallAdapter(ServiceMethod.java:232) ... 16もっと

build.gradle:

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' 

RetrofitInterface.java:

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<Response<ResponseBody>> downloadFileByUrlRx(@Url String fileUrl); 
} 

MainActivity.java:

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 <T> T createService(Class<T> 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<Response<ResponseBody>, Observable<File>> processResponse(){ 
    return new Function<Response<ResponseBody>, Observable<File>>() { 
     @Override 
     public Observable<File> apply(Response<ResponseBody> responseBodyResponse) throws Exception { 
      return saveToDiskRx(responseBodyResponse); 
     } 
    }; 
} 

private Observable<File> saveToDiskRx(final Response<ResponseBody> response){ 
    return Observable.create(new ObservableOnSubscribe<File>() { 
     @Override 
     public void subscribe(ObservableEmitter<File> 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<File> handleResult(){ 
    return new Observer<File>() { 
     @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"); 
     } 
    }; 
} 
} 

述べたように、私はhereは、それがどのように見えるのコールを追加しようとしました:それは見つけることができないよう

Call<Observable<Response<ResponseBody>>> downloadFileByUrlRx(@Url String fileUrl); 

しかし、これはflatMap機能に問題が発生しますシンボルメソッドflatMap(Function < Response < ResponseBody>、Observable <ファイル>>)。

答えて

39

あなたはRxJava バリアントと交換し、レトロフィット用RxJava アダプタを使用している:レトロフィットバージョン2.2.0以降で

//compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' 
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' 

UPDATE

ファーストパーティコールがありますRxJava2用アダプタ:

compile 'com.squareup.retrofit2:retrofit:2.2.0' 
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' 
+1

に更新されます! –

-3

レスポンスヘッダーを使用しているため、ResponseBodyObjectに置き換えてください。

12

新規出会い(7月/ 2017年):

あなたのライブラリーバージョンは確かに乱れています。

私はRXAndroid 2.0.1

compile 'io.reactivex.rxjava2:rxandroid:2.0.1' 
compile 'io.reactivex.rxjava2:rxjava:2.1.0' 
compile 'com.squareup.retrofit2:retrofit:2.3.0' 
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 

1の最新バージョンを使用している)あなたが同じ改修を持っており、レトロフィット - RxJavaアダプタを確認してください。使用しない

compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' 

compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 

をコンパイルしRxJava2CallAdapterFactory.create()代わりにRxJavaCallAdapterFactory.create()改造を構築しながら使用

2)。

更新:11月/ 2017

Rxjavaバージョンは、あなたが私のベーコンを救っ2.1.5

compile 'io.reactivex.rxjava2:rxandroid:2.0.1' 
compile 'io.reactivex.rxjava2:rxjava:2.1.5' 
compile 'com.squareup.retrofit2:retrofit:2.3.0' 
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 
+3

と 'RxJavaCallAdapterFactory.create()'の代わりに 'RxJava2CallAdapterFactory.create()'を使用してください。 –

+1

ありがとうございます。私はそれで答えを更新しました。 –

+1

また、** rx.schedulers.Schedulers **の代わりに** io.reactivex.schedulers.Schedulers **を使用してください –

関連する問題