侧边栏壁纸
博主头像
Gstory's Blog 博主等级

每天进步一点点!

  • 累计撰写 108 篇文章
  • 累计创建 23 个标签
  • 累计收到 11 条评论

目 录CONTENT

文章目录

MVVM中对Retrofit的生命周期的管理

gstory
2020-04-03 / 0 评论 / 0 点赞 / 139 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2023-10-08,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

最近对之前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();
    }
0

评论区