【问题标题】:Android - Using RxJava with Retrofit causes an IllegalArgumentExceptionAndroid - 将 RxJava 与 Retrofit 一起使用会导致 IllegalArgumentException
【发布时间】:2019-08-04 12:46:18
【问题描述】:

我尝试使用 RxJava 和 Retrofit 在 Android 中链接网络请求。但正如我在标题中所说,它会导致 IllegalArgumentException。在下面,您可以看到我到目前为止编写的代码(我还包含了导入和 gradle 文件以及我用于项目的依赖项):

ApiClient.java:

import retrofit2.Retrofit;

import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Path;
import rx.Observable;


public class ApiClient {

    // trailing slash is needed
    public static final String BASE_URL = "....";

    private static CliqueDBApiInterface sCliqueDBApiInterface;

    public static CliqueDBApiInterface getCliqueDBApiInterface(){

        if(sCliqueDBApiInterface == null){
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();

            sCliqueDBApiInterface = retrofit.create(CliqueDBApiInterface.class);
        }

        return sCliqueDBApiInterface;
    }

    public interface CliqueDBApiInterface{
        @GET("statementsOfClique/{idOfClique}")
        //Call<ListOfStatements> getStatementsOfTheClique(@Path("idOfClique") int id, @Header("Authorization") String authHeader );
        Observable<ListOfStatements> getStatementsOfTheClique(@Path("idOfClique") int id, @Header("Authorization") String authHeader );
    }

}

MainActivity.java:

import retrofit2.HttpException;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

// ... some other code

Observable<ListOfStatements> call = service.getStatementsOfTheClique(clique.getId(), authenticationToken);

call.subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<ListOfStatements>() {
          @Override
          public void onNext(ListOfStatements listOfStatements) {
              // Called once the `ListOfStatements` object is available
              List<Statement> statementList = listOfStatements.getStatementsOfClique();
              // do something with statementList


          }

          @Override
          public void onCompleted() {
             // Nothing to do here
          }

          @Override
          public void onError(Throwable e) {
             if (e instanceof HttpException) {
                int code = ((HttpException) e).code();
             }

          }
});

现在是 gradle 文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.celik.abdullah.hefuxi11"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions{
        exclude 'META-INF/rxjava.properties'
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.android.support:cardview-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
    implementation 'io.reactivex:rxandroid:1.2.0'
    implementation 'io.reactivex:rxjava:1.1.4'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'

}

但应用程序崩溃,我在 LogCat 中收到以下错误/异常:

03-13 18:36:29.190 4128-4128/com.celik.abdullah.hefuxi11 E/AndroidRuntime:致命异常:主要 进程:com.celik.abdullah.hefuxi11,PID:4128 java.lang.IllegalArgumentException:无法为 rx.Observable 创建调用适配器 对于方法 CliqueDBApiInterface.getStatementsOfTheClique 在改造2.Utils.methodError(Utils.java:52) 在 retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:60) 在 retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:34) 在 retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:36) 在 retrofit2.Retrofit.loadServiceMethod(Retrofit.java:168) 在 retrofit2.Retrofit$1.invoke(Retrofit.java:147) 在 java.lang.reflect.Proxy.invoke(Proxy.java:913) 在 $Proxy1.getStatementsOfTheClique(未知来源) 在 com.celik.abdullah.hefuxi11.adapters.CliqueAdapter$1.run(CliqueAdapter.java:124) 在 android.os.Handler.handleCallback(Handler.java:790) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:164) 在 android.app.ActivityThread.main(ActivityThread.java:6494) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 引起:java.lang.IllegalArgumentException:找不到调用适配器 rx. 可观察的。 试过: * retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory * retrofit2.CompletableFutureCallAdapterFactory * retrofit2.ExecutorCallAdapterFactory 在 retrofit2.Retrofit.nextCallAdapter(Retrofit.java:239) 在 retrofit2.Retrofit.callAdapter(Retrofit.java:203) 在 retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:58) ... 14 更多

有人知道如何解决这个问题吗?我发现了有关此异常的其他一些 SO 问题,并通过播放/更改 gradle 文件中的导入包尝试了所有答案,但没有任何效果。在构建改造实例时,我还添加了 addCallAdapterFactory(RxJava2CallAdapterFactory.create()),但我遇到了同样的错误。

提前致谢,

【问题讨论】:

    标签: java android retrofit2 rx-java2


    【解决方案1】:

    是的,要么将所有内容更新到 RxJava2,要么您可以使用 RxJava1

    在这种情况下,您的导入将类似于:

    /* rx */
    implementation 'io.reactivex:rxandroid:1.2.1'
    implementation 'io.reactivex:rxjava:1.3.2'
    
    /* retrofit, gson */
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'
    implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'
    

    然后你的 RetrofitApiInterface 会是这样的:

    public static CliqueDBApiInterface getCliqueDBApiInterface(){
    
        if(sCliqueDBApiInterface == null){
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(okHttpClient)
                    .build();
    
            sCliqueDBApiInterface = retrofit.create(CliqueDBApiInterface.class);
        }
    
        return sCliqueDBApiInterface;
    }
    
    
    where okHttpClient = new OkHttpClient.Builder().build();
    

    【讨论】:

      【解决方案2】:

      您正在使用 RxJava 1.x 的 observable 和订阅者。你已经在.addCallAdapterFactory(RxJava2CallAdapterFactory.create())添加了 RxJava 2.x 的适配器工厂@

      你应该从 RxJava 2.x 导入

      因此,您还需要更新依赖项

      implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
      implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
      implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
      
      
      
      
      import io.reactivex.Observable;
      import io.reactivex.schedulers.Schedulers;
      import io.reactivex.android.schedulers.AndroidSchedulers;
      import io.reactivex.disposables.CompositeDisposable;
      

      【讨论】:

        【解决方案3】:

        要紧接着创建一个调用,请使用flatMap operator,而不是在您的subscribe() 方法中创建Subscriber

        【讨论】:

          猜你喜欢
          • 2011-08-05
          • 2017-07-02
          • 1970-01-01
          • 2019-09-19
          • 2014-01-28
          • 2019-12-31
          • 2011-06-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多