我正在尝试使用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
您正在使用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()方法公开所有正在进行的调用。您可以编写代码,以按标签,主机或其他方式选择调用,然后在不