Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何让RXerorHandlingCallAdapterFactory?_Android_Error Handling_Rx Java_Retrofit2_Rx Android - Fatal编程技术网

Android 如何让RXerorHandlingCallAdapterFactory?

Android 如何让RXerorHandlingCallAdapterFactory?,android,error-handling,rx-java,retrofit2,rx-android,Android,Error Handling,Rx Java,Retrofit2,Rx Android,我找到了 但是在新版本中,在CallAdapter上编译'com.squareup.reformation2:adapter rxjava:2.2.0' CallAdapter 如果来自CallAdapter免责声明:我是您引用的博客文章的作者 最初的文章是为了证明RXJava2的概念,所以我也可以更容易地用这个版本来解释,但我会尝试涵盖更多的内容。我猜您使用的是版本1,因为您谈论的是adapterxjava,而不是adapter-rxjava2。也就是说,版本1的实现应该非常简单,只需使用正确

我找到了

但是在新版本
中,在CallAdapter上编译'com.squareup.reformation2:adapter rxjava:2.2.0'
CallAdapter

如果来自
CallAdapter
免责声明:我是您引用的博客文章的作者

最初的文章是为了证明RXJava2的概念,所以我也可以更容易地用这个版本来解释,但我会尝试涵盖更多的内容。我猜您使用的是版本1,因为您谈论的是
adapterxjava
,而不是
adapter-rxjava2
。也就是说,版本1的实现应该非常简单,只需使用正确的导入即可

以下是我使用RxJava 2所做的工作:

class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
  private final RxJava2CallAdapterFactory original;

  private RxErrorHandlingCallAdapterFactory() {
    original = RxJava2CallAdapterFactory.create();
  }

  public static CallAdapter.Factory create() {
    return new RxErrorHandlingCallAdapterFactory();
  }

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    return new RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit));
  }

  private static class RxCallAdapterWrapper<R> implements CallAdapter<R, Object> {
    private final Retrofit retrofit;
    private final CallAdapter<R, Object> wrapped;

    public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<R, Object> wrapped) {
        this.retrofit = retrofit;
        this.wrapped = wrapped;
    }

    @Override
    public Type responseType() {
        return wrapped.responseType();
    }

    @Override
    public Object adapt(Call<R> call) {
        Object result = wrapped.adapt(call);
        if (result instanceof Single) {
            return ((Single) result).onErrorResumeNext(new Function<Throwable, SingleSource>() {
                @Override
                public SingleSource apply(@NonNull Throwable throwable) throws Exception {
                    return Single.error(asRetrofitException(throwable));
                }
            });
        }
        if (result instanceof Observable) {
            return ((Observable) result).onErrorResumeNext(new Function<Throwable, ObservableSource>() {
                @Override
                public ObservableSource apply(@NonNull Throwable throwable) throws Exception {
                    return Observable.error(asRetrofitException(throwable));
                }
            });
        }

        if (result instanceof Completable) {
            return ((Completable) result).onErrorResumeNext(new Function<Throwable, CompletableSource>() {
                @Override
                public CompletableSource apply(@NonNull Throwable throwable) throws Exception {
                    return Completable.error(asRetrofitException(throwable));
                }
            });
        }

        return result;
    }

    private RetrofitException asRetrofitException(Throwable throwable) {
        // We had non-200 http error
        if (throwable instanceof HttpException) {
            HttpException httpException = (HttpException) throwable;
            Response response = httpException.response();
            return RetrofitException.httpError(response.raw().request().url().toString(), response, retrofit);
        }
        // A network error happened
        if (throwable instanceof IOException) {
            return RetrofitException.networkError((IOException) throwable);
        }

        // We don't know what happened. We need to simply convert to an unknown error

        return RetrofitException.unexpectedError(throwable);
    }
  }
}
类RXerorHandlingCallAdapterFactory扩展CallAdapter.Factory{
私人最终RxJava2CallAdapterFactory原件;
专用RXerorHandlingCallAdapterFactory(){
original=RxJava2CallAdapterFactory.create();
}
public static CallAdapter.Factory create(){
返回新的RxErrorHandlingCallAdapterFactory();
}
@凌驾
public CallAdapter get(类型returnType,注释[]注释,改装){
返回新的RxCallAdapterWrapper(改型,original.get(返回类型,注释,改型));
}
私有静态类RxCallAdapterWrapper实现CallAdapter{
私人最终改装;
私有最终呼叫适配器;
公用RxCallAdapterWrapper(改装,CallAdapter包装){
此。改装=改装;
this.wrapped=wrapped;
}
@凌驾
公共类型responseType(){
返回wrapped.responseType();
}
@凌驾
公共对象适配(调用){
对象结果=wrapped.adapt(调用);
如果(单个的结果实例){
返回((单个)结果).onErrorResumeNext(新函数(){
@凌驾
public SingleSource apply(@NonNull Throwable Throwable)引发异常{
返回Single.error(asException(throwable));
}
});
}
if(可观测的结果实例){
返回((可观察的)结果).onErrorResumeNext(新函数(){
@凌驾
public observesource apply(@NonNull Throwable Throwable)引发异常{
返回可观察到的错误(异常(可丢弃));
}
});
}
if(Completable的结果实例){
返回((可完成的)结果).onErrorResumeNext(新函数(){
@凌驾
public CompletableSource apply(@NonNull Throwable Throwable)引发异常{
返回Completable.error(asException(throwable));
}
});
}
返回结果;
}
专用改装例外情况ASRefundationException(可丢弃可丢弃){
//我们遇到了非200 http错误
if(HttpException的可丢弃实例){
HttpException HttpException=(HttpException)可丢弃;
Response-Response=httpException.Response();
返回reformationException.httpError(response.raw().request().url().toString(),response,reformation);
}
//发生网络错误
if(IOException的可丢弃实例){
返回异常.networkError((IOException)throwable);
}
//我们不知道发生了什么。我们需要简单地转换为未知错误
返回异常。异常错误(可丢弃);
}
}
}
没有大的变化,只是一些返回类型。现在,如果您看一下
RxJava2CallAdapter
,它实现了
CallAdapter
,那么我们需要考虑这一点

然后,我为实例类型添加了一些检查,以确保返回的内容正确

真正重要的部分是确保导入正确的包。改装适配器检查特定类别。我遇到的一个问题是导入错误,并且我检查可丢弃的
是否是
com.jakewharton.infract2.adapter.HttpException
的实例,而实际上它是
infract2.adapter.rxjava2.HttpException
的实例

希望这有助于更新到
kotlin
样式和

rxjava1:

com.squareup.2:adapter rxjava:2.5.0
with
io.reactivex:rxjava:1.3.8

RXerorHandlingCallAdapterFactory.kt

import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.HttpException
import retrofit2.Retrofit
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
import rx.Observable
import java.io.IOException
import java.lang.reflect.Type

/**
 * Created by Nikolay Unuchek on 28.11.2016.
 */

internal class RxErrorHandlingCallAdapterFactory private constructor() : CallAdapter.Factory() {
    private val original: RxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create()

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit) ?: return null)
    }

    private class RxCallAdapterWrapper<R>(
        private val retrofit: Retrofit,
        private val wrapped: CallAdapter<R, *>
    ) : CallAdapter<R, Any> {

        override fun responseType(): Type {
            return wrapped.responseType()
        }

        override fun adapt(call: Call<R>): Any {
            val result = wrapped.adapt(call)
            if (result is Observable<*>) {
                return result.onErrorResumeNext { throwable -> Observable.error(asRetrofitException(throwable as Throwable)) }
            }

            return result
        }

        private fun asRetrofitException(throwable: Throwable): RetrofitException {
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return RetrofitException.httpError(response.raw().request.url.toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                RetrofitException.networkError(throwable)
            } else RetrofitException.unexpectedError(throwable)

            // We don't know what happened. We need to simply convert to an unknown error

        }
    }

    companion object {

        fun create(): CallAdapter.Factory {
            return RxErrorHandlingCallAdapterFactory()
        }
    }
}
import retrofit2.HttpException
import retrofit2.Response
import java.io.IOException
class RetrofitException
private constructor(
    message: String?,
    /**
     * The request URL which produced the error.
     */
    val url: String?,
    /**
     * Response object containing status code, headers, body, etc.
     */
    val response: Response<*>?,
    /**
     * The event kind which triggered this error.
     */
    val kind: Kind,
    exception: Throwable
) : RuntimeException(message, exception) {

    override fun toString(): String {
        return super.toString() + " : " + kind + " : " + url + " : " + response?.errorBody()?.string()
    }

    /**
     * Identifies the event kind which triggered a [RetrofitException].
     */
    enum class Kind {
        /**
         * An [IOException] occurred while communicating to the server.
         */
        NETWORK,
        /**
         * A non-200 HTTP status code was received from the server.
         */
        HTTP,
        /**
         * An internal error occurred while attempting to execute a request. It is best practice to
         * re-throw this exception so your application crashes.
         */
        UNEXPECTED
    }

    companion object {
        fun httpError(url: String, response: Response<*>, httpException: HttpException): RetrofitException {
            val message = response.code().toString() + " " + response.message()
            return RetrofitException(message, url, response, Kind.HTTP, httpException)
        }

        fun networkError(exception: IOException): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.NETWORK, exception)
        }

        fun unexpectedError(exception: Throwable): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.UNEXPECTED, exception)
        }

        fun asRetrofitException(throwable: Throwable): RetrofitException {
            if (throwable is RetrofitException) {
                return throwable
            }
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return httpError(response.raw().request().url().toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                networkError(throwable)
            } else unexpectedError(throwable)
            // We don't know what happened. We need to simply convert to an unknown error
        }
    }
}
import by.gramophone.api.errorhandling.RetrofitException.Companion.asRetrofitException
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.functions.Function
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.lang.reflect.Type



/**
 * Created by Nikolay Unuchek on 28.11.2016.
 */

internal class RxErrorHandlingCallAdapterFactory private constructor() : CallAdapter.Factory() {
    private val original = RxJava2CallAdapterFactory.create()

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return RxCallAdapterWrapper(original.get(returnType, annotations, retrofit) ?: return null)
    }

    private class RxCallAdapterWrapper<R>(private val wrapped: CallAdapter<R, *>) : CallAdapter<R, Any> {

        override fun responseType(): Type {
            return wrapped.responseType()
        }

        override fun adapt(call: Call<R>): Any {
            return when (val result = wrapped.adapt(call)) {
                is Single<*> -> result.onErrorResumeNext(Function { throwable -> Single.error(asRetrofitException(throwable)) })
                is Observable<*> -> result.onErrorResumeNext(Function { throwable -> Observable.error(asRetrofitException(throwable)) })
                is Completable -> result.onErrorResumeNext (Function{ throwable -> Completable.error(asRetrofitException(throwable)) } )
                else -> result
            }

        }
    }

    companion object {
        fun create(): CallAdapter.Factory {
            return RxErrorHandlingCallAdapterFactory()
        }
    }
}
import retrofit2.HttpException
import retrofit2.Response
import java.io.IOException
class RetrofitException
private constructor(
    message: String?,
    /**
     * The request URL which produced the error.
     */
    val url: String?,
    /**
     * Response object containing status code, headers, body, etc.
     */
    val response: Response<*>?,
    /**
     * The event kind which triggered this error.
     */
    val kind: Kind,
    exception: Throwable
) : RuntimeException(message, exception) {

    override fun toString(): String {
        return super.toString() + " : " + kind + " : " + url + " : " + response?.errorBody()?.string()
    }

    /**
     * Identifies the event kind which triggered a [RetrofitException].
     */
    enum class Kind {
        /**
         * An [IOException] occurred while communicating to the server.
         */
        NETWORK,
        /**
         * A non-200 HTTP status code was received from the server.
         */
        HTTP,
        /**
         * An internal error occurred while attempting to execute a request. It is best practice to
         * re-throw this exception so your application crashes.
         */
        UNEXPECTED
    }

    companion object {
        fun httpError(url: String, response: Response<*>, httpException: HttpException): RetrofitException {
            val message = response.code().toString() + " " + response.message()
            return RetrofitException(message, url, response, Kind.HTTP, httpException)
        }

        fun networkError(exception: IOException): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.NETWORK, exception)
        }

        fun unexpectedError(exception: Throwable): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.UNEXPECTED, exception)
        }

        fun asRetrofitException(throwable: Throwable): RetrofitException {
            if (throwable is RetrofitException) {
                return throwable
            }
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return httpError(response.raw().request().url().toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                networkError(throwable)
            } else unexpectedError(throwable)
            // We don't know what happened. We need to simply convert to an unknown error
        }
    }
}
kt

import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.HttpException
import retrofit2.Retrofit
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
import rx.Observable
import java.io.IOException
import java.lang.reflect.Type

/**
 * Created by Nikolay Unuchek on 28.11.2016.
 */

internal class RxErrorHandlingCallAdapterFactory private constructor() : CallAdapter.Factory() {
    private val original: RxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create()

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return RxCallAdapterWrapper(retrofit, original.get(returnType, annotations, retrofit) ?: return null)
    }

    private class RxCallAdapterWrapper<R>(
        private val retrofit: Retrofit,
        private val wrapped: CallAdapter<R, *>
    ) : CallAdapter<R, Any> {

        override fun responseType(): Type {
            return wrapped.responseType()
        }

        override fun adapt(call: Call<R>): Any {
            val result = wrapped.adapt(call)
            if (result is Observable<*>) {
                return result.onErrorResumeNext { throwable -> Observable.error(asRetrofitException(throwable as Throwable)) }
            }

            return result
        }

        private fun asRetrofitException(throwable: Throwable): RetrofitException {
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return RetrofitException.httpError(response.raw().request.url.toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                RetrofitException.networkError(throwable)
            } else RetrofitException.unexpectedError(throwable)

            // We don't know what happened. We need to simply convert to an unknown error

        }
    }

    companion object {

        fun create(): CallAdapter.Factory {
            return RxErrorHandlingCallAdapterFactory()
        }
    }
}
import retrofit2.HttpException
import retrofit2.Response
import java.io.IOException
class RetrofitException
private constructor(
    message: String?,
    /**
     * The request URL which produced the error.
     */
    val url: String?,
    /**
     * Response object containing status code, headers, body, etc.
     */
    val response: Response<*>?,
    /**
     * The event kind which triggered this error.
     */
    val kind: Kind,
    exception: Throwable
) : RuntimeException(message, exception) {

    override fun toString(): String {
        return super.toString() + " : " + kind + " : " + url + " : " + response?.errorBody()?.string()
    }

    /**
     * Identifies the event kind which triggered a [RetrofitException].
     */
    enum class Kind {
        /**
         * An [IOException] occurred while communicating to the server.
         */
        NETWORK,
        /**
         * A non-200 HTTP status code was received from the server.
         */
        HTTP,
        /**
         * An internal error occurred while attempting to execute a request. It is best practice to
         * re-throw this exception so your application crashes.
         */
        UNEXPECTED
    }

    companion object {
        fun httpError(url: String, response: Response<*>, httpException: HttpException): RetrofitException {
            val message = response.code().toString() + " " + response.message()
            return RetrofitException(message, url, response, Kind.HTTP, httpException)
        }

        fun networkError(exception: IOException): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.NETWORK, exception)
        }

        fun unexpectedError(exception: Throwable): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.UNEXPECTED, exception)
        }

        fun asRetrofitException(throwable: Throwable): RetrofitException {
            if (throwable is RetrofitException) {
                return throwable
            }
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return httpError(response.raw().request().url().toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                networkError(throwable)
            } else unexpectedError(throwable)
            // We don't know what happened. We need to simply convert to an unknown error
        }
    }
}
import by.gramophone.api.errorhandling.RetrofitException.Companion.asRetrofitException
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.functions.Function
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.lang.reflect.Type



/**
 * Created by Nikolay Unuchek on 28.11.2016.
 */

internal class RxErrorHandlingCallAdapterFactory private constructor() : CallAdapter.Factory() {
    private val original = RxJava2CallAdapterFactory.create()

    override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
        return RxCallAdapterWrapper(original.get(returnType, annotations, retrofit) ?: return null)
    }

    private class RxCallAdapterWrapper<R>(private val wrapped: CallAdapter<R, *>) : CallAdapter<R, Any> {

        override fun responseType(): Type {
            return wrapped.responseType()
        }

        override fun adapt(call: Call<R>): Any {
            return when (val result = wrapped.adapt(call)) {
                is Single<*> -> result.onErrorResumeNext(Function { throwable -> Single.error(asRetrofitException(throwable)) })
                is Observable<*> -> result.onErrorResumeNext(Function { throwable -> Observable.error(asRetrofitException(throwable)) })
                is Completable -> result.onErrorResumeNext (Function{ throwable -> Completable.error(asRetrofitException(throwable)) } )
                else -> result
            }

        }
    }

    companion object {
        fun create(): CallAdapter.Factory {
            return RxErrorHandlingCallAdapterFactory()
        }
    }
}
import retrofit2.HttpException
import retrofit2.Response
import java.io.IOException
class RetrofitException
private constructor(
    message: String?,
    /**
     * The request URL which produced the error.
     */
    val url: String?,
    /**
     * Response object containing status code, headers, body, etc.
     */
    val response: Response<*>?,
    /**
     * The event kind which triggered this error.
     */
    val kind: Kind,
    exception: Throwable
) : RuntimeException(message, exception) {

    override fun toString(): String {
        return super.toString() + " : " + kind + " : " + url + " : " + response?.errorBody()?.string()
    }

    /**
     * Identifies the event kind which triggered a [RetrofitException].
     */
    enum class Kind {
        /**
         * An [IOException] occurred while communicating to the server.
         */
        NETWORK,
        /**
         * A non-200 HTTP status code was received from the server.
         */
        HTTP,
        /**
         * An internal error occurred while attempting to execute a request. It is best practice to
         * re-throw this exception so your application crashes.
         */
        UNEXPECTED
    }

    companion object {
        fun httpError(url: String, response: Response<*>, httpException: HttpException): RetrofitException {
            val message = response.code().toString() + " " + response.message()
            return RetrofitException(message, url, response, Kind.HTTP, httpException)
        }

        fun networkError(exception: IOException): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.NETWORK, exception)
        }

        fun unexpectedError(exception: Throwable): RetrofitException {
            return RetrofitException(exception.message, null, null, Kind.UNEXPECTED, exception)
        }

        fun asRetrofitException(throwable: Throwable): RetrofitException {
            if (throwable is RetrofitException) {
                return throwable
            }
            // We had non-200 http error
            if (throwable is HttpException) {
                val response = throwable.response()
                return httpError(response.raw().request().url().toString(), response, throwable)
            }
            // A network error happened
            return if (throwable is IOException) {
                networkError(throwable)
            } else unexpectedError(throwable)
            // We don't know what happened. We need to simply convert to an unknown error
        }
    }
}
导入2.HttpException
2.回应
导入java.io.IOException
类异常
私有构造函数(
消息:字符串?,
/**
*产生错误的请求URL。
*/
val url:字符串?,
/**
*包含状态代码、标题、正文等的响应对象。
*/
val响应:响应?,
/**
*触发此错误的事件类型。
*/
瓦尔·金德:金德,
例外:可丢弃
):RuntimeException(消息、异常){
重写funtostring():String{
返回super.toString()+“:“+kind+”:“+url+”:“+response?.errorBody()?.string()
}
/**
*标识触发[Exception]的事件类型。
*/
枚举类{
/**
*与服务器通信时发生[IOException]。
*/
网络,,
/**
*从服务器接收到非200 HTTP状态代码。
*/
HTTP,,
/**
*尝试执行请求时发生内部错误。最佳做法是
*重新引发此异常,使应用程序崩溃。
*/
想不到的
}
伴星{
有趣的httpError(url:String,response:response,httpexe