复杂版MVP

作者: 夜沐下的星雨 | 来源:发表于2020-07-23 18:57 被阅读0次

相对于简单版 复杂版可以减少代码量,方便后续在数据很大的情况下做修改
如下图:


Mode层:

//相当于model 的基类
//将<?> 全部改成T
//mode 抽取
public abstract class BaseRepository {
    //创建consumer 并是他为空
    public Consumer empty= o ->{};
    //创建两个参数的方法 第一个参数(第一次加载,刷新,加载更多,get/post方法) 第二个参数是 callback
    public <T> void doRequest(MvpRequest request,IBaseCallBack<T> callBack){
        doRequest(request,empty,callBack);
    }

    public <T> void doRequest(MvpRequest request, Consumer<T> consumer, IBaseCallBack<T> callBack) {
        //判断get/post 防止重复代码的产生
        switch (request.getRequestMethod()) {
            case GET:
               doObserver(request,DataService.getService().doGet(request.getUrl(),request.getHeaders(),request.getParams()),consumer,callBack);
                break;
            case POST:
                doObserver(request,DataService.getService().doPost(request.getUrl(),request.getHeaders(),request.getParams()),consumer,callBack);
                break;
        }

    }
    //创建私有的方法
    private<T> void doObserver(MvpRequest request,Observable<String> observable,Consumer<T> consumer,IBaseCallBack<T> callBack){
        observable.map(jsonData(callBack)).doOnNext(consumer).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<T>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull T t) {
                        callBack.onSuccess(t);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                       // callBack.onFail(e.getMessage());
                        callBack.onFail("失败");
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
    //将map的内容提取出来写入方法中
    public <T> Function<String ,T> jsonData(IBaseCallBack<T> callBack){
        return new Function<String, T>() {
            @Override
            public T apply(String s) throws Throwable {
                //将得到的json 串进行解析得到想要的数据
                //获取callback 的到的数据如:    HttpResult<ColumnData>
                //type集合
                Type[] types = callBack.getClass().getGenericInterfaces();
                //第0个 是ColumnData 的一个引用
                ParameterizedType parameterizedTypes = (ParameterizedType) types[0];
                //在通过引用  得到ColumnData 的实体对象
                Type type=parameterizedTypes.getActualTypeArguments()[0];
                //而返回的是HttpResult<ColumnData> 形式的数据? 创建一个工具类来继承ParameterizedType 得到的是HttpResult<T> 的实体对象
                ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(HttpResult.class, new Type[]{type});
                //gson 解析
                HttpResult<T> result= new Gson().fromJson(s, parameterizedType);

                if (result.getCode() == 1) {
                    if (result.getData() != null) {
                        return result.getData();
                    } else {
                        throw new Exception("服务器异常");
                    }
                } else {
                    throw new Exception("服务器异常");
                }
            }
        };

    }

ParameterizedTypeImpl :创建一个工具类来继承ParameterizedType 得到的是HttpResult<T> 的实体对象

public class ParameterizedTypeImpl implements ParameterizedType {
    private Type rawType;

    private Type [] typeArgs;

    public ParameterizedTypeImpl(Type rawType, Type[] typeArgs) {
        this.rawType = rawType;
        this.typeArgs = typeArgs;
    }

    @NonNull
    @Override
    public Type[] getActualTypeArguments() {
        return typeArgs;
    }

    @NonNull
    @Override
    public Type getRawType() {
        return rawType;
    }

    @Nullable
    @Override
    public Type getOwnerType() {
        return null;
    }
}

MvpRequest :创建mvpRequest 我们不知道需要多少功能 ,多少参数 所有创建MVPRequest 可以在需要的时候选择要传的参数


public class MvpRequest {
    protected String url;
    protected RequestType requestType = RequestType.FIRST;  // 第一次请求 0,刷新1 加载更多2
    protected RequestMethod requestMethod; // 1 post,2 get
    protected HashMap<String,Object> params; // 请求参数
    protected HashMap<String,Object> headers; // 请求头

    //构造方法参数是url
    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 params;
    }

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

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

    public void setHeaders(HashMap<String, Object> headers) {
        this.headers = headers;
    }
    //枚举:
    public enum RequestType{
        FIRST,REFRESH,LOAD_MORE
    }

    public enum RequestMethod{
        GET,POST
    }
}

GetRequest :当请求是get的请求时创建

public class GetRequest extends MvpRequest {

    public GetRequest(String url) {
        super(url);
    }

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

PostRequest :当请求时post 的请求创建

public class PostRequest extends MvpRequest{

    public PostRequest(String url) {
        super(url);
    }

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

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

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;
    }
}

IBaseCallBack

public interface IBaseCallBack<T> {
    void onSuccess(T t);
    void onError(String error);
}

ParamsUtils (获取公有参数)


/*
*公有参数
 **/
public class ParamsUtils {

    private static String SHA1_KEY = "K;9)Bq|ScMF1h=Vp5uA-G87d(_fi[aP,.w^{vQ:W";


    public static HashMap<String,Object> getCommonParams(){

        HashMap<String,Object> hashMap = new HashMap();

        hashMap.put(KEY_FROM, VALUE_FROM);

        hashMap.put(KEY_LANG, VALUE_LANG);


        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String nonce = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));


        hashMap.put(KEY_NONCE, nonce);
        hashMap.put(KEY_TIMESTAMP, timestamp);

        hashMap.put(KEY_SIGNATURE,getSHA1(timestamp, nonce));


        return hashMap;
    }



    public static  String getSHA1(String timestamp, String nonce) {
        try {
            String[] array = new String[]{SHA1_KEY, timestamp, nonce};
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < 3; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();

            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }
}


public interface Contrast {
    String BASE_URL="https://www.seetao.com";
    String VALUE_FROM = "android";
    String VALUE_LANG="zh";
    interface RequestKey{
        String KEY_FROM="from";
        String KEY_LANG="lang";
        String KEY_TIMESTAMP="timestamp";
        String KEY_NONCE="nonce";
        String KEY_SIGNATURE="signature";
    }

}

Bean抽取

public class HttpResult<T> {
    /**
     * 'code': '1',
     * 'message': '成功提示',
     * 'data':
     */
    private int code;
    private String message;
    private  T data;
    public HttpResult(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    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;
    }
}

IBaeMode

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

IBasePresenter

public interface IBasePresenter <V extends IBaseView>{
    void bindView(V view);
    void unBindView();
    Context getMVPContext();
}

IBaseView

public interface IBaseView <P extends IBasePresenter> {
    P createPresenter();
    Context getMVPContext();
}

BasePresenter

public class BasePresenter<V extends IBaseView> implements IBasePresenter<V> {
    protected V mView;
    @Override
    public void bindView(V view) {
        mView=view;
    }

    @Override
    public void unBindView() {
        mView=null;
    }

    @Override
    public Context getMVPContext() {
        if (mView!=null){
            return mView.getMVPContext();
        }
        return null;
    }
}

BaseFragment

public abstract class BaseFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View inflate = inflater.inflate(getLayout(), container, false);
        return inflate;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView();
    }

    protected abstract int getLayout();

    protected void initView() {
    }
    protected <T extends View> T findViewById(@IdRes int id){
        return getView().findViewById(id);
    }

    protected void showToast(String mag){
        Toast.makeText(getContext(), mag, Toast.LENGTH_SHORT).show();
    }

    protected void showToast(@StringRes int id){
        Toast.makeText(getContext(), id, Toast.LENGTH_SHORT).show();

    }
}

BaseMVPFragment

public abstract class BaseMVPFragment <P extends IBasePresenter>extends BaseFragment implements IBaseView<P>{
    protected P mPresenter;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter=createPresenter();
        mPresenter.bindView(this);
    }

    @Override
    public Context getMVPContext() {
        return getContext();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mPresenter.unBindView();
    }
}

以上为MVP的中级抽取: 如下是使用MVP

定义所需的接口

public interface ColumnContract {
    interface columnView extends IBaseView<columnPresenter> {
        void onDataSuccess(ColumnData columnData);
        void onFail(String mag);
        void onNotError();
    }
    //也可以不写   没有调用  用了IBaseModel
    interface columnModel extends IBaseModel {
        void columnMode(MvpRequest request, IBaseCallBack<ColumnData> callBack);
    }
    interface columnPresenter extends IBasePresenter<columnView> {
        void Presenter();
    }
}

定义所需的Persenter

public class ColumnPresenter extends BasePresenter<ColumnContract.columnView> implements ColumnContract.columnPresenter {
    private IBaseModel baseModel;

    public ColumnPresenter() {
        baseModel=new BaseRepository();
    }

    @Override
    public void Presenter() {
        if (!AppUtils.isOnInternet(getMVPContext())){
            mView.onNotError();
            return;
        }
        GetRequest getRequest = new GetRequest("/api/column/columnmanagelist");
        HashMap<String, Object> commonParams = ParamsUtils.getCommonParams();
        getRequest.setParams(commonParams);
        baseModel.doRequest(getRequest, new IBaseCallBack<ColumnData>() {
            @Override
            public void onSuccess(ColumnData columnData) {
                mView.onDataSuccess(columnData);
            }

            @Override
            public void onError(String error) {
                mView.onFail(error);
            }
        });
    }
}

定义Fragment

public class ColumnFragment extends BaseMVPFragment<ColumnContract.columnPresenter> implements ColumnContract.columnView {

    private TextView text;

    @Override
    protected int getLayout() {
        return R.layout.fragment_column;
    }

    @Override
    protected void initView() {
        super.initView();
        text = findViewById(R.id.text_view);
        mPresenter.Presenter();

    }

    @Override
    public void onDataSuccess(ColumnData columnData) {
        text.setText(Arrays.toString(columnData.getList().getMyColumn().toArray()));
    }

    @Override
    public void onFail(String mag) {
        showToast(mag);
    }

    @Override
    public void onNotError() {
        showToast("网络没网");
    }

    @Override
    public ColumnContract.columnPresenter createPresenter() {
        return new ColumnPresenter();
    }
}

相关文章

网友评论

    本文标题:复杂版MVP

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