目前还有很多项目使用Retrofit2+LiveData进行API请求,LiveData在不像RxJava那样可以方便地进行Error处理,所以想基于LiveData封装一个工具类,对API请求中的Error/Loading等进行统一处理

HttpManager

open class HttpManager(context: Context, serviceClass: Class) {    private val BASE_URL: String = context.getString(R.string.wallet_api_url)    private var isLoading: MutableLiveData? = null    private var error: MutableLiveData? = null    private val service = getRetrofit(            serviceClass,            BASE_URL,            getHttpClient(context)    )    fun init(            isLoading: MutableLiveData? = null,            error: MutableLiveData? = null    ):T {        this.isLoading = isLoading        this.error = error        return service    }    private fun createHeader(context: Context, request: Request): Request {        return request.newBuilder()                .addHeader("Accept", "application/json")                .build()    }    private fun getHttpClient(context: Context) : OkHttpClient {        val interceptor = Interceptor { chain ->            val response =  chain.proceed(createHeader(context, chain.request()))            if(response.code() != ErrorCode.HTTP_OK_200.httpErrorCode) {                try {                    val source =  response.body()?.source()                    source?.request(java.lang.Long.MAX_VALUE)                    val bodyString = source?.buffer?.clone()?.readString(Charset.forName("UTF-8")).toString()                    val errorBase = Gson().fromJson(bodyString, ErrorBase::class.java)                    error?.postValue(ErrorResponse(response.code(), errorBase))                } catch (e: Exception) {                    error?.postValue(ErrorResponse(response.code(), ErrorBase("Unknown Error", null)))                }            }            response        }        return OkHttpClient.Builder()                .addInterceptor(interceptor)                .addInterceptor(getLoggingInterceptor())                .eventListener(object: EventListener(){                    override fun callStart(call: Call) {                        isLoading?.postValue(true)                        super.callStart(call)                    }                    override fun callEnd(call: Call) {                        isLoading?.postValue(false)                        super.callEnd(call)                    }                })                .readTimeout(5, TimeUnit.SECONDS)                .connectTimeout(5, TimeUnit.SECONDS)                .build()    }    private fun getLoggingInterceptor(): HttpLoggingInterceptor {        val logging = HttpLoggingInterceptor()        if (BuildConfig.DEBUG) {            logging.level = HttpLoggingInterceptor.Level.BODY        } else {            logging.level = HttpLoggingInterceptor.Level.NONE        }        return logging    }    private fun getRetrofit(serviceClass: Class, baseUrl: String, httpClient: OkHttpClient) : T {        val retrofit: Retrofit = Retrofit.Builder()                .baseUrl(baseUrl)                .addConverterFactory(getConverter())                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .client(httpClient)                .build()        return retrofit.create(serviceClass)    }    private fun getConverter() : Converter.Factory {        return GsonConverterFactory.create(GsonBuilder()                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)                .create())    }}

HttpManager类中主要完成以下工作:

  1. 基于apiService创建Retofit,
  2. 通过EventListener处理loading状态
  3. 通过Interceptor处理Error

ExampleApi

class ExampleApi(context: Context ) : HttpManager< ExampleApi. ExampleService (    context, ExampleService::class.java) {    interface ExampleService {        @POST("/user/setting")        fun setting(): Call    }    fun setting(responseLiveData: MutableLiveData,                 isLoading: MutableLiveData?, error: MutableLiveData?) {        GlobalScope.launch {            init(isLoading, error)                    .setting()                    .enqueue(object: Callback {                        override fun onFailure(call: Call,                                                 t: Throwable) {                             //error处理由HttpManager负责,故此处 nothing to do                        }                            override fun onResponse(call: Call,                                            response: retrofit2.Response) {                            if (response.isSuccessful) {                                responseLiveData.postValue(response.body())                            }                        }                    })        }    }    data class ExampleResponse(            val hoge: Boolean,            val fuga: String    )}

ExampleApi主要工作:

  1. 提供API请求的调用方法, 并接受LiveData参数
  2. 继承HttpManager,通过Retrofit进行Api请求

Activity

val response = MutableLiveData()val error = MutableLiveData()val isLoading = MutableLiveData()WalletUserApi(this).setting(response, isLoading, error)response.observeForever { result ->    Toast.makeText(this, "response: $result", Toast.LENGTH_SHORT ).show()}error.observeForever { result ->    Toast.makeText(this, "response: $result", Toast.LENGTH_SHORT ).show()}isLoading.observeForever {     //プログレスダイアログ出したりDatabindingでいい感じにする}

Activity做的事情比较简单,调用Api类并传入LiveData即可。

LIveData可以放入ViewModel管理,在Activity范围内所有的Fragment或者自定义View等可以方便及时地订阅Api请求过程的最新状态。

更多相关文章

  1. Android(安卓)web services8 参数介绍
  2. cocos2dx中利用xcode 调用java中的函数
  3. Android中的Java与JavaScript方法互调
  4. android baseadapter的getview调用两次
  5. ArcGIS for Android示例解析之GP服务调用-----ViewShed
  6. Android(安卓)day_11-2 (服务)
  7. android RecyclerView局部刷新
  8. Android(安卓)cookies正确的更新方式
  9. Android(安卓)service跨进程调用和启动检查

随机推荐

  1. picasso-强大的Android图片下载缓存库
  2. 关于Android 横竖屏切换的问题
  3. Android IMF 分析
  4. Android 蓝牙浅析
  5. Android SDK的安装与环境变量配置
  6. appium 并发测试
  7. 备忘---Android(安卓)Permission
  8. Android(安卓)View与SurfaceView的手绘板
  9. Android调用系统前置相机拍照
  10. android 模拟2048