web-dev-qa-db-ja.com

RxAndroidおよびRetrofit:io.reactivex.Observable <retrofit2.Response <okhttp3.ResponseBody >>の呼び出しアダプターを作成できません

RxJava、rxAndroid、Retrofit2、およびOkHTTP3を使用して、URLエンドポイントからファイルをダウンロードしようとしています。私のコードは、「Observable <retrofit2.Response <okhttp3.ResponseBody >>」の呼び出しアダプターを作成できません。これらの方法は私にとって初めてなので、ここで重要な概念を見逃していると思います。方向やポイントは大歓迎です。

致命的な例外:メインプロセス:com.example.khe11e.rxdownloadfile、PID:14130 Java.lang.IllegalArgumentException:レトロフィット2.ServiceMethod $ Builder.methodError(ServiceMethodのメソッドRetrofitInterface.downloadFileByUrlRxのio.reactivex.Observable>の呼び出しアダプターを作成できません.Java:720)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)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.dispatchMe ssage(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メソッド)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 at retrofit2.Retrofit.nextCallAdapter(Retrofit.Java:237)at retrofit2.Retrofit.callAdapter(Retrofit.Java:201)at 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");
        }
    };
}
}

前述のようにCallを追加しようとしました here のようになります:

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

ただし、これにより、flatMap(Function <Response <ResponseBody>、Observable <File >>)というシンボルメソッドが見つからないため、flatMap関数で問題が発生します。

12
khe11e

RxJavaを使用しています1 Retrofitのアダプター、RxJavaに置き換えます2バリアント:

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

[〜#〜] update [〜#〜]

レトロフィットバージョン2.2.0 RxJava2用のファーストパーティコールアダプタがあります。

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

更新日:2019年6月

Rxjavaバージョンが2.2.10に更新されました

_compile 'io.reactivex.rxjava2:rxandroid:2.1.1'
compile 'io.reactivex.rxjava2:rxjava:2.2.10'
compile 'com.squareup.retrofit2:retrofit:2.6.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.6.0'
_

また、Retrofitには少なくともJava 7またはAndroid 2.3

_------------------------------------------
_

新規参入者(2017年7月):

あなたは確かにあなたのライブラリのバージョンを台無しにしました。

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)同じRetrofitおよびRetrofit-RxJavaアダプターがあることを確認します。

2)コンパイルを使用する

_compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' 
_

じゃない

_compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
_

そして、レトロフィットを構築するときに、RxJava2CallAdapterFactory.create()の代わりにRxJavaCallAdapterFactory.create()を使用します。

21
Zumry Mohamed