Android笔记
我的博客
Android笔记
Android笔记
  • Android学习资料
  • Android知识点梳理
  • Android Studio
  • aop
  • UI
    • ViewPager2
    • View
      • View.post()分析
      • 自定义View
        • Canvas使用
        • Paint使用
        • Path使用
        • PathMeasure使用
        • Matrix使用
      • View事件分发
    • TextView
    • EditText
    • 引导页
    • 菜单
    • Toolbar
    • RecyclerView
    • ViewPager
    • BottomSheet
    • 通知
    • CalendarView
    • TimePicker
    • LayoutInfalter
    • shadowlayout
    • 状态栏适配
    • RecyclerView
    • 屏幕适配
  • 组件
    • Activity
    • Intent
    • 服务
      • 服务
      • 绑定服务
      • AIDL
    • Broadcasts
    • Fragment
    • ContentProvider
  • 权限
  • 数据存储
    • 数据和文件存储
    • 将文件保存到外部存储中
    • 将文件保存在内部存储中
    • Android 存储用例和最佳做法
    • 保存键值对数据
  • 编译时注解
    • Untitled
    • Java注解处理器](annotation/annotation-processing.md)
    • JavaPoet 文档翻译
  • 图形和图像
    • Drawable使用
  • 网络
    • WebView
    • OkHttp文档翻译
      • OkHttp使用
      • OkHttp拦截器
    • Retrofit使用
    • Retrofit源码分析
    • HttpURLConnection使用
    • Volley使用
    • Volley源码分析
    • Glide使用
    • Glide源码分析
    • RxJava
  • 插件化
    • 插件化框架
    • VirtualAPK分析
  • 依赖注入
  • 开源库
    • EventBus源码分析
    • Okio概览
    • Okio菜谱
    • Okio
    • OkHttp拦截器
    • OKHttp缓存
    • Okhttp源码分析
  • 集合
    • SparseArray
    • ArrayMap
  • 架构
  • Jetpack
    • databinding adapter
    • databinding坑
    • databinding源码分析
    • Android Data Binding: Let’s Flip This Thing
    • Untitled
    • Lifecycle源码分析
    • ViewModel源码分析
    • LiveData源码分析
  • 音频和视频
    • CameraX使用
    • ExoPlayer
    • GsyVideoPlayer
  • 性能优化
    • 崩溃优化
    • 内存优化
      • LeakCanary如何工作
    • 渲染优化
    • 电池优化
    • 启动优化
    • 网络优化
    • 安装包大小优化
  • NDK开发
  • 系统源码分析
    • Android源码下载
    • Android系统启动
      • init进程启动过程
      • Zygote进程启动过程
      • Zygote进程启动流程
      • SystemServer处理过程
    • 应用程序进程启动过程
      • 应用程序进程启动过程介绍
    • Window
    • WMS
    • WindowManagerService
    • 四大组件的工作过程
      • Activity启动流程分析
      • Activity启动流程
    • ActivityManagerService分析
    • Context详解
    • Binder原理
      • Binder驱动
      • 获取ServiceManager
      • 启动ServiceManager
      • Parcel源码分析
    • Android图形系统概述
    • Choreographer原理
    • Handler使用
    • Handler源码分析
  • 逆向
    • Android抓包
    • 网易云音乐逆向
由 GitBook 提供支持
在本页
  • 添加依赖
  • 创建Retrofit
  • 服务器错误统一处理
  • 其他错误统一处理
在GitHub上编辑
  1. 网络

Retrofit使用

添加依赖

implementation "com.squareup.retrofit2:retrofit:2.8.1"
implementation "com.squareup.retrofit2:retrofit:2.8.1"
implementation "com.squareup.retrofit2:converter-gson:2.8.1"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.8.1"
implementation "com.squareup.okhttp3:okhttp:4.8.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.8.0"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"

创建Retrofit

interface ApiService {
    companion object{
        val instance:ApiService  by lazy{
            val okHttpClient = OkHttpClient.Builder()
                .build()
            val retrofit=Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl("")
                .build()
            retrofit.create(ApiService::class.java)
        }
    }
}

服务器错误统一处理

public class ApiErrorGsonConverterFactory extends Converter.Factory {

    private final Converter.Factory mDelegateFactory;

    public ApiErrorGsonConverterFactory(Converter.Factory delegateFactory) {
        mDelegateFactory = delegateFactory;
    }

    public static ApiErrorGsonConverterFactory create(Gson gson) {
        return new ApiErrorGsonConverterFactory(GsonConverterFactory.create(gson));
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return mDelegateFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations,
            retrofit);
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
        Retrofit retrofit) {
        final Converter<ResponseBody, ?> apiErrorConverter =
            mDelegateFactory.responseBodyConverter(ApiError.class, annotations, retrofit);
        final Converter<ResponseBody, ?> delegateConverter =
            mDelegateFactory.responseBodyConverter(type, annotations, retrofit);
        return (Converter<ResponseBody, Object>) value -> {
            MediaType mediaType = value.contentType();
            String stringBody = value.string();
            //优先解析ApiError
            ApiError apiError = apiErrorConverter.convert(ResponseBody.create(mediaType, stringBody));
            if (((ApiError) apiError).isError()) {
                throw (ApiError) apiError;
            }
            return delegateConverter.convert(ResponseBody.create(mediaType, stringBody));
        };
    }
}

其他错误统一处理

class RxErrorHandlingCallAdapterFactory : CallAdapter.Factory() {
    override fun get(
        returnType: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (getRawType(returnType) != Observable::class.java) {
            return null // Ignore non-Observable types.
        }
        //获取代理
        val delegate = retrofit.nextCallAdapter(
            this, returnType,
            annotations
        ) as CallAdapter<Any?, Observable<Any?>>

        return object : CallAdapter<Any?, Any?> {
            override fun adapt(call: Call<Any?>): Any {
                // Delegate to get the normal Observable...
                val observable = delegate.adapt(call)
                // ...and change it to send notifications to the observer on the specified scheduler.
                return observable.onErrorResumeNext(
                    Function<Throwable, ObservableSource<Any?>> { t ->
                        if (t is ApiError) {
                            Observable.error<Any>(t)
                        } else Observable.error<Any>(asRetrofitException(t))
                    })
                    .observeOn(AndroidSchedulers.mainThread())
            }

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

    private fun asRetrofitException(throwable: Throwable): RetrofitException {
        try {
            when (throwable) {
              is HttpException -> {
                  val response = throwable.response()
                  return RetrofitException.httpError(
                      response.raw().request().url().toString(), response
                  )
              }
                is IOException -> {
                    return RetrofitException.networkError(throwable)
                }
                is UnknownHostException -> {
                    return RetrofitException.networkError(throwable)
                }
            }
        } catch (e: Exception) {
            return RetrofitException.unexpectedError(e)
        }

        return RetrofitException.unexpectedError(throwable)
    }
}
public class RetrofitException extends RuntimeException {
    public static RetrofitException httpError(String url, Response response) {
        String message = response.code() + " " + response.message();
        return new RetrofitException(message, url, response, Kind.HTTP, null);
    }

    public static RetrofitException networkError(IOException exception) {
        String message = MyApp.getAppContext().getResources().getString(R.string.network_error);
        exception.printStackTrace();
        return new RetrofitException(message, null, null, Kind.NETWORK, exception);
    }

    public static RetrofitException unexpectedError(Throwable exception) {
        String message = MyApp.getAppContext().getResources().getString(R.string.unexpected_error);
        exception.printStackTrace();
        return new RetrofitException(message, null, null, Kind.UNEXPECTED, exception);
    }

    private final String url;
    private final Response response;
    private final Kind kind;

    public RetrofitException(String message, String url, Response response, Kind kind,
        Throwable exception) {
        super(message, exception);
        this.url = url;
        this.response = response;
        this.kind = kind;
    }

    /** The request URL which produced the error. */
    public String getUrl() {
        return url;
    }

    /** Response object containing status code, item_data, body, etc. */
    public Response getResponse() {
        return response;
    }

    /** The event kind which triggered this error. */
    public Kind getKind() {
        return kind;
    }
}
上一页OkHttp拦截器下一页Retrofit源码分析

最后更新于3年前

官方文档