美文网首页框架
MVP终极抽取(上)

MVP终极抽取(上)

作者: 夜沐下的星雨 | 来源:发表于2020-08-05 08:03 被阅读0次

流程图:

mvp终极.jpg

首先创建model 层 并且对他的请求参数,网络请求,数据参数,进行封装,这样可以减小相似代码。更简洁。

分包:

创建ApiService:

public interface ApiService {
    @POST
    @FormUrlEncoded
    Observable<String> doPost(@Url String url, @HeaderMap HashMap<String ,Object> headers, @FieldMap HashMap<String,Object> params);

    @GET
    Observable<String> doGet(@Url String url, @HeaderMap HashMap<String ,Object> headers, @QueryMap HashMap<String,Object> params);


}

创建DataService:

//网络 请求封装
//日志拦截器,Retrofit 的 公有部分抽取出来   使用了双检索单列模式
public class DataService {
    public static volatile ApiService mApiService;
    private static HttpLoggingInterceptor httpLoggingInterceptor;
    public static final int WAIT_TIME=20000;
    public static ApiService getApiService(){
        if (mApiService==null){
            //在多线程 防止线程抢占  类只有一个
            synchronized (DataService.class){
                if (mApiService==null){
                    httpLoggingInterceptor = new HttpLoggingInterceptor();
                    if (BuildConfig.DEBUG){
                        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                    }else {
                        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
                    }

                    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                            .addInterceptor(httpLoggingInterceptor)
                            .connectTimeout(WAIT_TIME, TimeUnit.SECONDS)
                            .writeTimeout(WAIT_TIME, TimeUnit.SECONDS)
                            .readTimeout(WAIT_TIME, TimeUnit.SECONDS)
                            .build();
                    Retrofit retrofit = new Retrofit.Builder().addConverterFactory(MvpGsonConverterFactory.create())
                            .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                            .client(okHttpClient)
                            .baseUrl(Contrast.BASE_URL)
                            .build();
                    mApiService=retrofit.create(ApiService.class);
                }
            }
        }
        return mApiService;
    }
}

MvpGsonConverterFactory, MvpGsonRequestBodyConverter

//Gson转换器工厂

public final class MvpGsonConverterFactory extends Converter.Factory {
    /**
     * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
     * decoding from JSON (when no charset is specified by a header) will use UTF-8.
     */
    public static MvpGsonConverterFactory create() {
        return create(new Gson());
    }

    /**
     * Create an instance using {@code gson} for conversion. Encoding to JSON and
     * decoding from JSON (when no charset is specified by a header) will use UTF-8.
     */
    @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
    public static MvpGsonConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        return new MvpGsonConverterFactory(gson);
    }

    private final Gson gson;

    private MvpGsonConverterFactory(Gson gson) {
        this.gson = gson;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new MvpGsonResponseBodyConverter<>(gson, adapter,type);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new MvpGsonRequestBodyConverter<>(gson, adapter);
    }
}
//请求体转换器
final class MvpGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
    private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
    private static final Charset UTF_8 = Charset.forName("UTF-8");

    private final Gson gson;
    private final TypeAdapter<T> adapter;

    MvpGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }

    @Override public RequestBody convert(T value) throws IOException {
        Buffer buffer = new Buffer();
        Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
        JsonWriter jsonWriter = gson.newJsonWriter(writer);
        adapter.write(jsonWriter, value);
        jsonWriter.close();
        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
    }
}
//响应体转换器
final class MvpGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson gson;
    private final TypeAdapter<T> adapter;
    private final Type type;

    MvpGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter,Type type) {
        this.gson = gson;
        this.adapter = adapter;
        this.type=type;
    }

    @Override public T convert(ResponseBody value) throws IOException {
        if (type==String.class){
            try {
                MediaType mediaType = value.contentType();
                //字符集
                Charset charset=null;
                if (mediaType!=null){
                    charset=mediaType.charset();
                }
                String json = new String(value.bytes(), charset == null ? StandardCharsets.UTF_8 : charset);
                return (T) handJson(json);
            }finally {
                value.close();
            }

        }else {
            JsonReader jsonReader = gson.newJsonReader(value.charStream());
            try {
                T result = adapter.read(jsonReader);
                if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                    throw new JsonIOException("JSON document was not fully consumed.");
                }
                return result;
            } finally {
                value.close();
            }
        }
    }
    public String handJson(String json){
        try {
            JSONObject jsonObject = new JSONObject(json);
            if (!jsonObject.isNull("code")){
                int code = jsonObject.getInt("code");
                if (code!=1){
                    if (!jsonObject.isNull("data")){
                        String data = jsonObject.getString("data");
                        if (TextUtils.isEmpty(data)){//如果data 是一个空字符串
                            jsonObject.remove("data");
                            return jsonObject.toString();
                        }
                    }
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }
}

创建MvpRequest:

//数据请求参数的封装
//使用面向对象的思想  : 通过bean 类  的形式将请求的数据封装到一个类中
public class MvpRequest <T>{
    protected String url;
    protected RequestType requestType=RequestType.FIRST;//第一次请求,刷新 ,加载更多
    protected RequestMethod requestMethod=RequestMethod.POST;//post get
    protected HashMap<String ,Object> mParams;
    protected HashMap<String ,Object> mHeaders;
    protected Class<T> type;
    protected boolean isEnableCancel;


    public MvpRequest() {
    }

    public Class<T> getType() {
        return type;
    }

    public void setType(Class<T> type) {
        this.type = type;
    }

    public MvpRequest(String url) {
        this.url = url;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public RequestType getRequestType() {
        return requestType;
    }

    public void setRequestType(RequestType requestType) {
        this.requestType = requestType;
    }

    public RequestMethod getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(RequestMethod requestMethod) {
        this.requestMethod = requestMethod;
    }

    public HashMap<String, Object> getParams() {
        return mParams;
    }

    public void setParams(HashMap<String, Object> mParams) {
        this.mParams = mParams;
    }

    public HashMap<String, Object> getHeaders() {
        //三目用算符  如果header ==null 就创建HashMap<>  否则传入headers
        return mHeaders == null ? new HashMap<>() : mHeaders;
    }

    public void setHeaders(HashMap<String, Object> mHeaders) {
        this.mHeaders = mHeaders;
    }

    public boolean isEnableCancel() {
        return isEnableCancel;
    }
    public void setEnableCancel(boolean enableCancel) {
        isEnableCancel = enableCancel;
    }

    //枚举形式的RequestType       固定几个参数
}

创建GetRequest:

public class GetRequest extends MvpRequest {
    public GetRequest(String url) {
        super(url);
    }

    @Override
    public RequestMethod getRequestMethod() {
        return RequestMethod.GET;
    }
}

创建PostRequest:

public class PostRequest  extends MvpRequest  {
    public PostRequest(String url) {
        super(url);
    }

    @Override
    public RequestMethod getRequestMethod() {
        return RequestMethod.POST;
    }
}

创建枚举RequestMethod

//对get   post 进行选择
public enum  RequestMethod {
    POST,GET
}

创建枚举RequestType :

//进行第一次 ,加载 ,刷新
public enum  RequestType {
    FIRST,REFRESH,LOAD_MORE
}

创建MvpResponse:

//数据结果参数的封装
public class MvpResponse<D> {
    private ResponseType type = ResponseType.SERVER;// 数据从哪儿回来的? 服务器,sdcard, 内存

    private RequestType requestType = RequestType.FIRST; // 是第一次请求回来?刷新回来?加载更多回来?

    private String msg; // 服务器给的消息提示

    private int code; // 服务器返回的状态码

    private D data; // 我们真正要的数据


    public boolean isOk(){
        return data != null;
    }


    public ResponseType getType() {
        return type;
    }

    public MvpResponse<D> type(ResponseType type) {
        this.type = type;
        return this;
    }

    public RequestType getRequestType() {
        return requestType;
    }

    public MvpResponse<D>  requestType(RequestType requestType) {
        this.requestType = requestType;
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public MvpResponse<D>  setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public int getCode() {
        return code;
    }

    public MvpResponse<D>  setCode(int code) {
        this.code = code;
        return this;
    }

    public D getData() {
        return data;
    }

    public MvpResponse<D>  setData(D data) {
        this.data = data;
        return this;
    }
}

创建枚举ResponseType :

//对  服务,sd卡,缓存
public enum  ResponseType {
    SERVER,MEMORY,SDCARD
}

创建IBaseCallBack:

//接口放实现类
public interface IBaseCallBack <T>{
    void onResult(MvpResponse<T> response);


    default void onStart(Disposable disposable){

    }
}

创建IBaseModel:

public interface IBaseModel {
    //做请求:两个参数: MvpRequest   CallBack
    <T> void doRequest(MvpRequest<T> request, IBaseCallBack<T> callBack);
}

创建BaseModel 进行model 的抽取:


public class BaseRepository implements IBaseModel {

    @SuppressWarnings("ALL")
    public Consumer empty= o ->{};//定义一个空的Consumer 有点时候调用三参方法

    public <T> void doRequest(MvpRequest<T> request,IBaseCallBack<T> callBack){
        doRequest(request,empty,callBack);
    }

    public <T> void doRequest(MvpRequest<T> request, Consumer<MvpResponse<T>> doBackground, IBaseCallBack<T> callBack) {
        //判断
        switch (request.getRequestMethod()) {
            case GET: {
                //创建观察者处理数据
                doObserver(request, DataService.getApiService().doGet(request.getUrl(), request.getHeaders(), request.getParams()), doBackground, callBack);
                break;
            }
            case POST: {
                doObserver(request, DataService.getApiService().doPost(request.getUrl(), request.getHeaders(), request.getParams()), doBackground, callBack);
                break;
            }
        }
    }

    protected <T> void doObserver(MvpRequest<T> request, Observable<String> observable, Consumer<MvpResponse<T>> consumer, IBaseCallBack<T> callBack) {

        observable//对数据进行加工
                .map(json2Data(request))
                //对数据做异常处理
                .doOnNext(consumer)
                //切换线程
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MvpResponse<T>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        if (request.isEnableCancel()) {
                            callBack.onStart(d);
                        }
                    }

                    @Override
                    public void onNext(@NonNull MvpResponse<T> data) {

                        callBack.onResult(data);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        callBack.onResult(new MvpResponse<T>().setMsg(e.getMessage()));
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
    public <T> Function<String,  MvpResponse<T>> json2Data(MvpRequest<T> request) {
        return new Function<String, MvpResponse<T>> () {
            @Override
            public MvpResponse<T> apply(String s) throws Throwable {
                // IBaseCallBack<ColumnData>

                    /*Type[] types = callBack.getClass().getGenericInterfaces();
                    ParameterizedType parameterizedType = (ParameterizedType) types[0];
                    Type realType = parameterizedType.getActualTypeArguments()[0];
                    */

                //HttpResult<ColumnData>
                ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(HttpResult.class, new Type[]{request.getType()});

                HttpResult<T> data = new Gson().fromJson(s, parameterizedType);
                if (data.getCode() == 1) {
                    if (data.getData() != null) {
                        return new MvpResponse<T>().setCode(data.getCode()).setData(data.getData());
                    } else {
                        return new MvpResponse<T>().setCode(data.getCode()).setMsg("服务器异常");
                    }
                } else {
                    return new MvpResponse<T>().setCode(data.getCode()).setMsg(data.getMessage());
                }
            }
        };
    }


}

相关文章

  • MVP终极抽取(上)

    流程图: 首先创建model 层 并且对他的请求参数,网络请求,数据参数,进行封装,这样可以减小相似代码。更简洁。...

  • MVP 终极抽取(下)

    流程图: 通过MVP终极抽取(上)让我们可以知道Model 的抽取。那么开始view ,presenter 的抽取...

  • MVP抽取

    为什么要抽取? 每一个页面都用到同样的内容,每次都写同样的代码,浪费;规定代码的编写规范;多人开发维护变得简单。 ...

  • Mvp抽取

    为什么要抽取? 每一个页面都用到同样的内容,每次都写同样的代码,浪费;规定代码的编写规范;多人开发维护变得简单。 ...

  • MVP抽取

    描述: 当我们的逻辑功能越来越多,每个功能点都要写一套MVP,是一件很繁琐的事情。因此我们要对MVP的进行封装和抽...

  • MVP抽取

    为什么要抽取? 每一个页面都用到同样的内容,每次都写同样的代码,浪费; 规定代码的编写规范; 多人开发维护变得简单...

  • MVP抽取

    一、抽取原因 每一个页面都用到同样的内容,每次都写同样的代码,浪费;规定代码的编写规范;多人开发维护变得简单。 二...

  • 自制MVP基类框架依赖库和工具类(自用)

    抽取 除了mvp层的抽取,还有对Activity、Adapter、Fragment的抽取 工具类 验证码工具类:C...

  • MVP抽取.md

    让子类的工作模式都按父类的执行 一个抽象类公开定义了执行它的方法的方式 网络抽取 HttpManager RxUt...

  • Mvp_抽取

    1.BaseActivity层 2.BaseCallBack层(与BaseView层相同) 3.Baseview层...

网友评论

    本文标题:MVP终极抽取(上)

    本文链接:https://www.haomeiwen.com/subject/qkvmrktx.html