Android 网络请求 Retrofit单独请求 和 retrofit+livedata请求

Retrofit网络请求

步骤:

1、设置路由地址

 Retrofit retrofit = new Retrofit
        .Builder()
        .baseUrl(ApiUtils.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

2、书写请求接口

public interface UserMgrService {
    /**
     * GET 用 Query
     */
    @GET("login")
    Call<UserBean> login(@Query("username") String username, @Query("password") String password);
}

3、实现请求接口

UserMgrService service = retrofit.create(UserMgrService.class);

4、获取call对象

Call<UserBean> call = service.login( mAccountEdit.getText().toString(), mPasswordEdit.getText().toString());

5、发送请求

5.1 同步请求
Response<UserBean> response = call.execute();
Log.d("123123", "msg--" + response.body().getUser_head_img());
5.2 异步请求
//回调
call.enqueue(new Callback<UserBean>() {
    @Override
    public void onResponse(Call<UserBean> call, Response<UserBean> response) {
        Log.d("123123", "msg--" + response.body().getUser_head_img());
    }
    @Override
    public void onFailure(Call<UserBean> call, Throwable t) {
        // 失败时做处理
    }
});

Retrofit+liveData

Retrofit 和 LiveData 结合的⼀种实现⽅法

  1. 构建 Retrofit 对象时,添加⼀个转换适配器⼯⼚ CallAdapterFactory
  2. CallAdapterFactory ⽣产的适配器 CallAdapter 需要重写两个⽅法
    *responseType()
    *adapt()
    responseType()⽤于返回从GSON数据到JAVA对象的类型
    adapt()该⽅法⽤于将 Retrofit 请求返回时的 Call对象转换为需要的类,这⾥为我们⾃定义的 LiveData对象,为了后续监听⽹络回调,这⾥CallAdapterFactory 构建 CallAdapter 时需要传递当前 Call 实例
  3. 我们⾃定义的 LiveData 对象需要重写
    *onActive()
    onActive()该⽅法在 LiveData 实例的 observer 由 0变1 时会调⽤,我们传递进来的 Call 在这⾥使⽤。
    由于⽹络线程在后台运⾏,此时应该对 Call 实例 enqueue ⼀个 Callback,Callback 重写的⽅法中对 LiveData 进⾏onResponse()调用postValue<T>()
    这样我们的LiveData在有observer后就能及时收到请求的回调并进⾏更新

具体实现

1、实现CallAdapterFactory

class LiveDataCallAdapterFactory : CallAdapter.Factory() {
    override fun get(
        returnType: Type,
        annotations: Array<out Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (getRawType(returnType) != LiveData::class.java) return null
        //获取第一个泛型类型
        val observableType = getParameterUpperBound(0, returnType as ParameterizedType)
        return LiveDataCallAdapter<Any>(observableType)

    }
}

2、实现CallAdapter

class LiveDataCallAdapter<T>(private val responseType: Type):CallAdapter<T,LiveData<T>>{
    override fun responseType(): Type {
        return responseType
    }

    override fun adapt(call: Call<T>): LiveData<T> {
        return object : LiveData<T>() {
            private val started = AtomicBoolean(false)
            override fun onActive() {
                super.onActive()
                if (started.compareAndSet(false, true)) {//确保执行一次

                    call.enqueue(object : Callback<T> {
                        override fun onFailure(call: Call<T>, t: Throwable) {
                            postValue(null)
                        }

                        override fun onResponse(call: Call<T>, response: Response<T>) {
                            postValue(response.body())
                        }
                    })
                }
            }
        }
    }


}

3、将LiveDataCallAdapterFactory和retrofit 关联

private void initRetrofit() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        //1、初始话OKhttp
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)  //设置请求超市时间
                .readTimeout(60,TimeUnit.SECONDS) //设置读取超时时间
                .writeTimeout(60,TimeUnit.SECONDS) //设置写入超时时间
                .retryOnConnectionFailure(true) //设置出现错误时重连
                .addInterceptor(new HeadIntercept())
                .addInterceptor(loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
                .build();
        //2、初始化retrofitl
        retrofit = new Retrofit.Builder()
                .client(client)
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .addCallAdapterFactory(new LiveDataCallAdapterFactory())
                .build();
    }

4、网络请求接口

public interface UserMgrServiceLiveData {

    //post 传body
    @POST("api/medical/applogin")
    LiveData<UserNewsBean> login(@Body UserBean body);
}

5、调用

 UserBean userBean= new UserBean();
        userBean.setIdcard(userName);
        userBean.setPassword(pwd);
      apiService.login(userBean).observe((LifecycleOwner) context, new Observer<UserNewsBean>() {
          @Override
          public void onChanged(UserNewsBean userNewsBeanApiResponse) {
              Log.e( "onChanged: ",userNewsBeanApiResponse.toString());
          }
      });

完成上边就可以使用liveData+retrofit进行网络请求了
但是,这并不是它的最终形态。
如果我们后台返回的接口是统一的格式:
例如是:

{
	data:[],//或者{}
	errorCode:0,
	errorMsg:""
}

那么我们可以定义已个统一的处理类

class ApiResponse<T> (
    var data: T?,
    var errorCode: Int,
    var errorMsg:String
)

然后在我们的CallAdapterFactory类中做响应的调整如下即添加
val rawType = getRawType(observableType)
if (rawType != ApiResponse::class.java) {
throw IllegalArgumentException(“type must be ApiResponse”)
}
if (observableType !is ParameterizedType) {
throw IllegalArgumentException(“resource must be parameterized”)
}
这些代码

class LiveDataCallAdapterFactory : CallAdapter.Factory() {
    override fun get(
        returnType: Type,
        annotations: Array<out Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        if (getRawType(returnType) != LiveData::class.java) return null
        //获取第一个泛型类型
        val observableType = getParameterUpperBound(0, returnType as ParameterizedType)
        val rawType = getRawType(observableType)
        if (rawType != ApiResponse::class.java) {
            throw IllegalArgumentException("type must be ApiResponse")
        }
        if (observableType !is ParameterizedType) {
            throw IllegalArgumentException("resource must be parameterized")
        }
        return LiveDataCallAdapter<Any>(observableType)

    }
}

最后调整我们的请求接口类如下

public interface UserMgrServiceLiveData {

    //post 传body
    @POST("api/medical/applogin")
    LiveData<ApiResponse<UserNewsBean>> login(@Body UserBean body);
}

调用方式不变

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值