简体   繁体   English

RxAndroid 和 Retrofit:无法为 io.reactivex.Observable 创建调用适配器<retrofit2.Response<okhttp3.ResponseBody> &gt;

[英]RxAndroid and Retrofit: Unable to create call adapter for io.reactivex.Observable<retrofit2.Response<okhttp3.ResponseBody>>

I am trying use rxJava, rxAndroid, Retrofit2, and OkHTTP3 to download a file from a URL endpoint.我正在尝试使用 rxJava、rxAndroid、Retrofit2 和 OkHTTP3 从 URL 端点下载文件。 My code is unable to create the call adapter for an "Observable< retrofit2.Response< okhttp3.ResponseBody>>".我的代码无法为“Observable<retrofit2.Response<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.任何方向或点都非常感谢。

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.dispatchMe致命异常:主进程:com.example.khe11e.rxdownloadfile,PID:14130 java.lang.IllegalArgumentException:无法为 io.reactivex.Observable> 创建调用适配器,用于方法 RetrofitInterface.downloadFileByUrlRx at retrofit2.ServiceMethod$BuilderMethod.methodError( .java:720) at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:234) atretrofit2.ServiceMethod$Builder.build(ServiceMethod.java:160) atretrofit2.Retrofit.loadServiceMethod(Retrofit.java:166) atretrofit2 .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.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 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>. 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) Method) at 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> 的调用适配器。 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尝试过:*retrofit2.adapter.rxjava.RxJavaCallAdapterFactory *retrofit2.ExecutorCallAdapterFactory atretrofit2.Retrofit.nextCallAdapter(Retrofit.java:237) atretrofit2.Retrofit.callAdapter(Retrofit.java:201) atretrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod) .java:232) ... 16 个

build.gradle:构建.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:改造接口.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:主活动.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");
        }
    };
}
}

I've tried adding Call as mentioned here so it looks like:我试过添加这里提到的 Call ,所以它看起来像:

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

however this causes issues with the flatMap function as it cannot find symbol method flatMap(Function< Response< ResponseBody>,Observable< File>>).但是这会导致 flatMap 函数出现问题,因为它找不到符号方法 flatMap(Function< Response< ResponseBody>,Observable< File>>)。

You are using RxJava 1 adapter for Retrofit, replace it with RxJava 2 variant:您正在使用 RxJava 1适配器进行改造,将其替换为 RxJava 2变体:

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

UPDATE更新

Starting with Retrofit version 2.2.0 there is a first-party call adapter for RxJava2:从 Retrofit 版本2.2.0开始,有一个用于 RxJava2 的第一方调用适配器:

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

Update : May/2020更新:2020 年 5 月

New adapter for RxJava 3 RxJava 3 的新适配器

implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'

RxJava3CallAdapterFactory.create() instead of RxJava2CallAdapterFactory.create() RxJava3CallAdapterFactory.create()而不是RxJava2CallAdapterFactory.create()


Update : June/2019更新:2019 年 6 月

Rxjava version is updated to 2.2.10 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'

Also Retrofit requires at minimum Java 7 or Android 2.3此外,Retrofit 至少需要 Java 7 或 Android 2.3

------------------------------------------

For new comers (July/2017) :对于新来者(2017 年 7 月):

You messed your library version for sure.你肯定搞砸了你的库版本。

I have been using latest version of RXAndroid 2.0.1我一直在使用最新版本的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) Make sure you have same Retrofit and Retrofit-RxJava Adapters. 1) 确保你有相同的 Retrofit 和 Retrofit-RxJava 适配器。

2) Use compile 2) 使用编译

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

not不是

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

and use RxJava2CallAdapterFactory.create() instead of RxJavaCallAdapterFactory.create() while building retrofit.并在构建改造时使用RxJava2CallAdapterFactory.create()而不是RxJavaCallAdapterFactory.create()

既然你使用了响应头,那么到处都将ResponseBody替换为Object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 改造:无法创建适配器 - Retrofit :Unable to create adapter Android:无法处理UnknownHostException [使用Retrofit 2,okhttp3,rxandroid 2] - Android: Unable to handle UnknownHostException [with Retrofit 2, okhttp3, rxandroid 2] Retrofit2 proguard发生:java.lang.AbstractMethodError:抽象方法“ void retrofit2.Callback.onResponse(retrofit2.Call,retrofit2.Response)” - Retrofit2 proguard occur: java.lang.AbstractMethodError: abstract method “void retrofit2.Callback.onResponse(retrofit2.Call, retrofit2.Response)” 如何从okhttp3.ResponseBody获取URL? - How to get url from okhttp3.ResponseBody? 等待适配器上的改造异步调用响应? - Wait for retrofit asynchronous call response on an adapter? 如何在 Retrofit 中创建用于挂起函数的调用适配器? - How to create a call adapter for suspending functions in Retrofit? 消耗来自Okhttp的One-Shot ResponseBody会导致Retrofit出现问题 - Consuming One-Shot ResponseBody from Okhttp causes issues with Retrofit java.lang.IllegalArgumentException:无法为接口改造创建调用适配器。Call - java.lang.IllegalArgumentException: Unable to create call adapter for interface retrofit.Call RxAndroid问题与改造? - RxAndroid issue with retrofit? 改装动态响应车身 - Retrofit Dynamic ResponseBody
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM