当前位置: 首页 > 面试题库 >

RxAndroid和翻新版:无法为io.reactivex.Observable创建呼叫适配器>

施赞
2023-03-14
问题内容

我正在尝试使用rxJava,rxAndroid,Retrofit2和OkHTTP3从URL端点下载文件。我的代码无法为“ Observable
<retrofit2.Response <okhttp3.ResponseBody

”创建呼叫适配器。这些方法对我来说是陌生的,因此我认为这里缺少一个重要的概念。任何方向或点将不胜感激。

的android.view.View.performClick(View.java:5207)的java:39)的android.os.Handler.handleCallback(Handler.java:746)的android.view.View
$
PerformClick.run(View.java:21168)的)在android.os.Handler.dispatchMessage(Handler.java:95)在android.os.Looper.loop(Looper.java:148)在android.app.ActivityThread.main(ActivityThread.java:5491)在java.lang
com.android.internal.os.ZygoteInit $
MethodAndArgsCaller.run(ZygoteInit.java:728)的com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)的.reflect.Method.invoke(本机方法)引起原因:java.lang.IllegalArgumentException:无法找到io.reactivex.Observable>的调用适配器。尝试过:*
retrofit2.adapter.rxjava.RxJavaCallAdapterFactory * retrofit2.ExecutorCallAdapterFactory位于retrofit2.Retrofit.nextCallAdapter(Retrofit.java:

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,因此它看起来像:

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

但是,这会导致flatMap函数出现问题,因为它找不到符号方法flatMap(Function ,Observable \ >)。


问题答案:

您正在使用RxJava 1 适配器进行翻新,将其替换为RxJava 2 变体:

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

更新

从Retrofit版本开始,2.2.0存在用于RxJava2的第一方呼叫适配器:

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


 类似资料:
  • 问题内容: 我正在使用SimpleXml改造2.0.0-beta1。我想从REST服务中检索简单(XML)资源。使用SimpleXML编组/解组Simple对象可以正常工作。 使用此代码(转换为2.0.0之前的代码)时: 服务: 我得到这个异常: 我想念什么?我知道用作品包装返回类型。但是我希望服务将业务对象作为类型返回(并在同步模式下工作)。 更新 添加了额外的依赖关系并根据不同的答案提出建议后

  • 我是RXJava的新手。在一个场景中,我希望调用第一个登录webservice(),如果成功,则希望调用另一个webservice()以获取用户信息。

  • 问题内容: 我需要创建一个可处理此类网络呼叫的改造呼叫适配器: 我希望它不使用Kotlin Coroutines 。我已经有了使用的成功实现,它可以处理以下方法: 但是我希望能够使函数成为挂起函数并删除包装器。 使用暂停功能,Retrofit的工作方式就像在返回类型周围有包装器一样,因此被视为 我的实施 我试图创建一个呼叫适配器来尝试解决这个问题。到目前为止,这是我的实现: 厂 适配器 使用此实现

  • 我有一个这样的改装实例 参数#2(questionKind)总是伴随对象中的常量字符串之一,我不知道它在说什么“类型变量或通配符”。我做错了什么?

  • 适配器目录和文件结构 适配器目录和文件结构布局的例子: /application/libraries/Driver_name Driver_name.php drivers Driver_name_subclass_1.php Driver_name_subclass_2.php Driver_name_subclass_3.php 注意: 为了在大小写敏感的文件系统上维持兼容性,这个 Drive

  • 问题内容: 我最近升级到OkHttp3,并注意到您不能再直接从客户端取消按标签呼叫。现在必须由应用程序处理。 在CHANGELOG中表示: 现在,取消批量呼叫是应用程序的责任。 删除了通过标签取消调用的API,并已将其替换为更通用的机制。调度程序现在通过其runningCalls()和queueedCalls()方法公开所有正在进行的调用。您可以编写代码,以按标签,主机或其他方式选择调用,然后在不