最近对之前MVP的封装库进行MVVM的改造,发现在MVVM中使用rxlifecycle、rxjava来控制Retrofit的生命周期感觉有点麻烦没必要,那么这个时候就可以使用livedata来对Retrofit进行管理。
修改的话很简单之前的Retorit封装都不怎么需要改动只要去掉rxjava封装的工厂,新增一个我们自己写的工厂来处理数据
Retrofit.Builder.addConverterFactory(GsonConverterFactory.create())
/**
* @Description: LiveDataCallAdapterFactory
* @Author: gstory
**/
public class LiveDataCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != LiveData.class) {
return null;
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Type rawType = getRawType(observableType);
if (rawType != ApiResponse.class) {
throw new IllegalArgumentException("resource must be ApiResponse");
}
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalArgumentException("resource must be parameterized");
}
return new LiveDataCallAdapter<>(observableType);
}
}
/**
* @Description: LiveDataCallAdapter
* @Author: gstory
* @CreateDate: 2021/4/20 16:00
**/
public class LiveDataCallAdapter<T> implements CallAdapter<T, LiveData<T>> {
private Type responseType;
LiveDataCallAdapter(Type responseType) {
this.responseType = responseType;
}
@Override
public Type responseType() {
return responseType;
}
@Override
public LiveData<T> adapt(final Call<T> call) {
return new MyLiveData<>(call);
}
private static class MyLiveData<T> extends LiveData<T> {
private AtomicBoolean start = new AtomicBoolean(false);
private final Call<T> call;
MyLiveData(Call<T> call) {
this.call = call;
}
@Override
protected void onActive() {
super.onActive();
if (start.compareAndSet(false, true)) {
call.enqueue(new Callback<T>() {
@Override
public void onResponse(@Nullable Call<T> call, @Nullable Response<T> response) {
T body = response.body();
postValue(body);
}
@Override
public void onFailure(@Nullable Call<T> call, @Nullable Throwable t) {
postValue((T) new ApiResponse<T>(0,0, t.getMessage(), null));
}
});
}
}
}
}
ApiResponse是自己根据业务接口定义的,比如
{
"result": 200,
"message": "",
"data": {
}
}
你可以这样写
/**
* @Description: ApiResponse
* @Author: gstory
**/
public class ApiResponse<T> {
private int result;
private String message;
private T data;
public ApiResponse(int result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ApiResponse{" +
"result=" + result +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
注意的是在server接口中需要使用LiveData,不要用Call、Observable等
/**
* @Description: 接口类
* @Author: gstory
* @CreateDate: 2021/4/20 16:11
**/
public interface ApiService {
@GET("data")
LiveData<ApiResponse<MyData>> getData();
}
接下来就可以在ViewModel愉快的调用了,而且不用操心接口泄漏的问题
/**
* 调用接口 返回数据
*
* @return
*/
public LiveData<ApiResponse<MyData>> getData() {
return Api.getNetService().getData();
}
评论区