MVP+Retrofit+Rxjava+DataBinding泛型架构模型

3 篇文章 0 订阅
2 篇文章 0 订阅

一. 用到的知识点:

        UI—面向对象 

        数据交互 —MVP模式

        网络图片加载—–glide

        json解析—–gson 

        http请求—retrofit2+rxjava2

        事件总线—-eventbus

        注解—DataBinding

二.目录结构

 

biz   —————————     业务模块

bridge  ————————    底层功能实现跟UI层的衔接层 

capabilities  ——————   底层功能具体实现

constant  ———————    常量 

ui  ——————————    界面

util ——————————   业务层公共方法 

view  —————————   自定义view实现

三.解析

1.UI层

用到面向对象的封装BaseActivity为基类,同时BaseActivity实现三个接口,分别为CreateInit,PublishActivityCallBack, PresentationLayerFunc,三个接口的作用依次是:界面初始化,页面跳转封装,页面交互封装。PresentationLayerFunc的具体实现是在PresentationLayerFuncHelper里面,BaseActivity类会初始化该类,把复杂的功能实现抽象出去,轻量化基类。

BaseActivity代码如下所示:

/**
 * * 备注:
 * 1.XXActivity 继承 BaseActivity,当页面存在 Presenter 时,具体 Activity 需要调用 setPresenter(P... presenter)
 * 2.支持一个 Activity 存在多个 Presenter
 *
 * @param <T>
 * @param <V>
 * @param <P> Data:2018/12/18
 * @author yong
 */
public abstract class BaseActivity<T, V extends IMvpView, P extends BasePresenter<V>> extends RxAppCompatActivity implements
        CreateInit.CreateInitActivity<V, P>, PublishActivityCallBack, PresentationLayerFunc, IMvpView<T>, View.OnClickListener {

    protected ActivityMvpDelegate mvpDelegate;

    private PresentationLayerFuncHelper presentationLayerFuncHelper;

    public final String TAG = this.getClass().getSimpleName();

    /**
     * Context对象
     */
    protected static Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getMvpDelegate().onCreate(savedInstanceState);

        presentationLayerFuncHelper = new PresentationLayerFuncHelper(this);
        setContentView(savedInstanceState);
        mContext = this;
        Constants.isStartFragmen = false;

        initData();
        initListeners();
        MyApplication.mApplication.addActivity(this);
        EventBus.getDefault().register(this);
    }

    /**
     * 注入View
     *
     * @return
     */
    @Override
    public V[] createView() {
        V[] views = null;
        P[] pArray = createPresenter();
        if (pArray != null) {
            views = (V[]) new IMvpView[pArray.length];
            for (int i = 0; i < pArray.length; i++) {
                views[i] = (V) this;
            }
        }
        return views;
    }

    /**
     * 关联Activity的生命周期
     *
     * @return
     */
    @NonNull
    protected ActivityMvpDelegate<V, P> getMvpDelegate() {
        if (mvpDelegate == null) {
            mvpDelegate = new ActivityMvpDelegateImpl(this, this);
        }
        return mvpDelegate;
    }

    /**
     * 事件线
     *
     * @param eventModel
     */
    @Subscribe
    public void onEventMainThread(T eventModel) {

    }

    /**
     * 链接Presenter
     *
     * @return
     */
    @Override
    public P[] createPresenter() {
        return getPresenterArray();
    }

    /**
     * 获取 Presenter 数组
     */
    public abstract P[] getPresenterArray();

    /**
     * 网络请求的错误信息,已在请求中处理提示Toast
     * 如果有特殊处理需重写
     *
     * @param action 区分不同事件
     * @param code   错误码
     * @param msg    错误信息
     */
    @Override
    public void onError(String action, int code, String msg) {

    }

    /**
     * 配合DataBinding点击事件监听
     * 添加防止重复点击
     * 有点击事件只需重写
     *
     * @param v
     */
    @Override
    public void onClick(View v) {
        if (Tools.isDoubleClick()) return;
    }

    @Override
    protected void onResume() {
        MyApplication.mApplication.currentActivityName = this.getClass().getName();
        getMvpDelegate().onResume();
        super.onResume();
    }

    @Override
    public void startActivity(Class<?> openClass, Bundle bundle) {
        Intent intent = new Intent(this, openClass);
        if (null != bundle)
            intent.putExtras(bundle);
        startActivity(intent);
    }

    @Override
    public void openActivityForResult(Class<?> openClass, int requestCode, Bundle bundle) {
        Intent intent = new Intent(this, openClass);
        if (null != bundle)
            intent.putExtras(bundle);
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void setResultOk(Bundle bundle) {
        Intent intent = new Intent();
        if (bundle != null) ;
        intent.putExtras(bundle);
        setResult(RESULT_OK, intent);
        finish();
    }

    @Override
    public void showToast(String msg) {
        presentationLayerFuncHelper.showToast(msg);
    }

    @Override
    public void showSoftKeyboard(View focusView) {
        presentationLayerFuncHelper.showSoftKeyboard(focusView);
    }

    @Override
    public void hideSoftKeyboard() {
        presentationLayerFuncHelper.hideSoftKeyboard();
    }

    @Override
    protected void onDestroy() {
        getMvpDelegate().onDestroy();
        MyApplication.mApplication.deleteActivity(this);
        EventBus.getDefault().unregister(this);
        Constants.isStartFragmen = true;

        super.onDestroy();
    }

    @Override
    public void finish() {
        try {
            presentationLayerFuncHelper.hideSoftKeyboard();
        } catch (Exception e) {
            LogUtil.E("finish 输入法错误");
        }
        super.finish();
    }

    //监听点击事件 实现点击页面上除EditView外的位置隐藏输入法
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        try {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                View v = getCurrentFocus();
                if (isShouldHideKeyboard(v, ev)) {
                    presentationLayerFuncHelper.hideKeyboard(v.getWindowToken());
                }
            }
        } catch (Exception e) {
            LogUtil.E("dispatchTouchEvent 输入法错误");
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘,因为当用户点击EditText时则不能隐藏
     *
     * @param v
     * @param event
     * @return
     */

    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击EditText的事件,忽略它。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
        return false;
    }



    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getMvpDelegate().onSaveInstanceState(outState);
    }

    @Override
    protected void onPause() {
        super.onPause();
        getMvpDelegate().onPause();
    }

    @Override
    protected void onStart() {
        super.onStart();
        getMvpDelegate().onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        getMvpDelegate().onStop();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        getMvpDelegate().onRestart();
    }

    @Override
    public void onContentChanged() {
        super.onContentChanged();
        getMvpDelegate().onContentChanged();
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        getMvpDelegate().onPostCreate(savedInstanceState);
    }
}

PresentationLayerFuncHelper代码如下所示:

/**
 * <页面基础公共功能实现>
 * Data:2018/12/18
 *
 * @author yong
 */
public class PresentationLayerFuncHelper implements PresentationLayerFunc {

    private Context context;

    public PresentationLayerFuncHelper(Context context) {
        this.context = context;
    }

    /**
     * Toast提示
     *
     * @param msg
     */
    @Override
    public void showToast(String msg) {
        ToastUtil.makeTextShort(context, msg);
    }

    /**
     * 显示软键盘
     *
     * @param focusView
     */
    @Override
    public void showSoftKeyboard(View focusView) {
        ((Activity) context).getWindow().getDecorView().postDelayed(new Runnable() {
            @Override
            public void run() {
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    focusView.requestFocus();
                    imm.showSoftInput(focusView, 0);
                }
            }
        }, 100);
    }

    /**
     * 隐藏软键盘
     */
    @Override
    public void hideSoftKeyboard() {
        if ((context == null || ((Activity) context).getWindow() == null)) {
            return;
        }
        View view = ((Activity) context).getWindow().peekDecorView();
        if (view == null || view.getWindowToken() == null) {
            return;
        }
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm == null) {
            return;
        }
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

    /**
     * 获取InputMethodManager,隐藏软键盘
     *
     * @param token
     */
    public void hideKeyboard(IBinder token) {
        if (token != null) {

            InputMethodManager im = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

            if (im != null) {

                im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);

            }
        }
    }
}

三个接口,分别为CreateInit, PublishActivityCallBack, PresentationLayerFunc代码如下所示:

/**
 * <公共方法抽象>
 * Data:2018/12/18
 *
 * @author yong
 */
public interface CreateInit<V extends IMvpView, P extends Presenter> {

    interface CreateInitActivity<V extends IMvpView, P extends Presenter> extends CreateInit<V, P> {
        /**
         * 设置布局文件
         */
        void setContentView(Bundle savedInstanceState);

    }

    interface CreateInitFragment<V extends IMvpView, P extends Presenter> extends CreateInit<V, P> {
        /**
         * 设置布局文件
         */
        View initView(LayoutInflater inflater);

    }

    /**
     * 连接P层
     *
     * @return
     */
    P[] createPresenter();

    /**
     * 注入view
     *
     * @return
     */
    V[] createView();

    /**
     * 初始化数据
     */
    void initData();

    /**
     * 增加按钮点击事件
     */
    void initListeners();

}
/**
 * <页面跳转封装>
 * Data:2018/12/18
 *
 * @author yong
 */
public interface PublishActivityCallBack {
    /**
     * 打开新界面
     *
     * @param openClass 新开页面
     * @param bundle    参数
     */
    void startActivity(Class<?> openClass, Bundle bundle);

    /**
     * 打开新界面,期待返回
     *
     * @param openClass   新界面
     * @param requestCode 请求码
     * @param bundle      参数
     */
    void openActivityForResult(Class<?> openClass, int requestCode, Bundle bundle);

    /**
     * 返回到上个页面
     *
     * @param bundle 参数
     */
    void setResultOk(Bundle bundle);
}
/**
 * <页面基础公共功能抽象>
 * Data:2018/12/18
 *
 * @author yong
 */
public interface PresentationLayerFunc {
    /**
     * 弹出消息
     *
     * @param msg
     */
    void showToast(String msg);

    /**
     * 显示软键盘
     *
     * @param focusView
     */
    void showSoftKeyboard(View focusView);

    /**
     * 隐藏软键盘
     */
    void hideSoftKeyboard();
}

界面只要继承BaseLoadActivity,而BaseLoadActivity继承BaseActivity:BaseLoadActivity是带空页面额错误显示页面

/**
 * <功能详细描述>
 * 泛型传入
 * 1、网络请求实体类:如果有多个实体类可以传入Object或是通过BaseListMode中set、get方法设置
 * 2、自动生成ViewDataBinding
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public class MainActivity extends BaseLoadActivity<LoginModel, ActivityMainBinding> {

    private LoginPresenter presenter = new LoginPresenter(this);

    @Override
    public int getLayout() {
        return R.layout.activity_main;
    }


    @Override
    public void onSuccess(String action, LoginModel data) {
        mLoadBinding.text.setText(SharedPrefManager.getUser().getString(SharedPrefUser.USER_NAME, ""));
        mLoadBinding.text1.setText(data.getNickName());
        mLoadBinding.bt.setText(action);
    }

    @Override
    public void initListeners() {
        mLoadBinding.bt.setOnClickListener(this);
    }

    @Override
    public void initData() {
//        presenter.login("", "123456");
    }

    @Override
    public BasePresenter<IMvpView<LoginModel>>[] getPresenterArray() {
        return new BasePresenter[]{presenter};
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
    }
}

2.数据交互层

Presenter与View交互是通过接口:成功,失败(如有特需处理可以使用此方法)。

/**
 * <功能详细描述>
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 * <p>
 * action 方式: 考虑多个请求时 根据 action 区分处理
 */
public interface IMvpView<T> {

    /**
     * 网络请求的错误信息,已在请求中处理提示Toast
     *
     * @param action 区分不同事件
     * @param code   错误码
     * @param msg    错误信息
     */
    @UiThread
    void onError(String action, int code, String msg);

    /**
     * 成功返回结果
     *
     * @param action 区分不同事件
     * @param data   数据
     */
    @UiThread
    void onSuccess(String action, T data);

}

LoginPresenter 为登录的业务实现类:1、业务处理。2.通知页面数据刷新。Presenter与页面交互是通过接口实现的,通过继承基类BasePresenter,从而实现接口attachView(V view),view是个泛型,MainActivity会实现这个接口,在初始化LoginPresenter 的时候,会把自身传过来loginPresenter.attachView(this),这段代码是在onCreate中,Presenter通知页面刷新。在使用BaseModelObserver或是BaseListModelObserver时提供两个构造器,多参数可以提示加载弹窗和设置点击返回键是否消失加载窗。

/**
 * <基础业务类>
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public interface Presenter<V> {

    /**
     * 将 View 添加到当前 Presenter
     *
     * @param view
     */
    @UiThread
    void attachView(@NonNull V view);

    /**
     * 将 View 从 Presenter 中移除
     */
    @UiThread
    void detachView();

    /**
     * 销毁 V 实例
     */
    @UiThread
    void destroy();
}
/**
 * <基础业务类>
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public abstract class BasePresenter<V extends IMvpView> implements Presenter<V> {

    private WeakReference<V> viewRef;

    private SecurityManager securityManager;

    private RetrofitHttp.Builder retrofitHttp;

    /**
     * 获取 View
     *
     * @return
     */
    @UiThread
    public V getMvpView() {
        return viewRef == null ? null : viewRef.get();
    }

    /**
     * 判断View是否已经添加
     *
     * @return
     */
    @UiThread
    public boolean isViewAttached() {
        return viewRef != null && viewRef.get() != null;
    }

    /**
     * 绑定 View
     *
     * @param view
     */
    @UiThread
    @Override
    public void attachView(V view) {
        viewRef = new WeakReference<>(view);
    }

    /**
     * 移除 View
     */
    @Override
    public void detachView() {
        if (viewRef != null) {
            viewRef.clear();
            viewRef = null;
        }
    }

    @Override
    public void destroy() {
    }

    /**
     * MD5加密
     */
    public SecurityManager getSecurityManager() {
        if (securityManager == null)
            securityManager = BridgeFactory.getBridge(Bridges.SECURITY);
        return securityManager;
    }

    /**
     * 网络请求
     */
    public RetrofitHttp.Builder getRetrofitHttp() {
        if (retrofitHttp == null)
            retrofitHttp = BridgeFactory.getBridge(Bridges.HTTP);
        retrofitHttp.clear();
        retrofitHttp.lifecycle((LifecycleProvider) getMvpView());
        return retrofitHttp;
    }
}
/**
 * <功能详细描述>
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public class LoginPresenter extends BasePresenter<IMvpView<LoginModel>> {

    private Context context;

    public LoginPresenter(Context context) {
        this.context = context;
    }

    public void login(String userid, String pwd) {

        if (!isViewAttached()) return;

        Map<String, Object> map = new HashMap<>();
        map.put("userid", userid);
        map.put("pwd", pwd);

        getRetrofitHttp().post().apiUrl(UrlConstans.LOGIN)
                .addParameter(map).build()
                .request(new BaseModelObserver<LoginModel>(context) {//BaseListModelObserver:返回数据List集合

                    @Override
                    public void onSuccess(String action, LoginModel value) {
                        getMvpView().onSuccess(action, value);
                    }

                    @Override
                    public void onError(String action, int code, String desc) {//有需要需重写
                        super.onError(action, code, desc);
                        getMvpView().onError(action, code, desc);
                    }
                });

    }
}

3.网络层

/**
 * Http请求类
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public class RetrofitHttp {

    /*请求方式*/
    private Method method;
    /*请求参数*/
    private Map<String, Object> parameter;
    /*header*/
    private Map<String, Object> header;
    /*LifecycleProvider*/
    private LifecycleProvider lifecycle;
    /*ActivityEvent*/
    private ActivityEvent activityEvent;
    /*FragmentEvent*/
    private FragmentEvent fragmentEvent;
    /*HttpObserver*/
    private HttpObserver httpObserver;
    /*标识请求的TAG*/
    private String tag;
    /*文件map*/
    private Map<String, File> fileMap;
    /*上传文件回调*/
    private UploadObserver uploadCallback;
    /*基础URL*/
    private String baseUrl;
    /*apiUrl*/
    private String apiUrl;
    /*String参数*/
    String bodyString;
    /*是否强制JSON格式*/
    boolean isJson;

    /*构造函数*/
    private RetrofitHttp(Builder builder) {
        this.parameter = builder.parameter;
        this.header = builder.header;
        this.lifecycle = builder.lifecycle;
        this.activityEvent = builder.activityEvent;
        this.fragmentEvent = builder.fragmentEvent;
        this.tag = builder.tag;
        this.fileMap = builder.fileMap;
        this.baseUrl = builder.baseUrl;
        this.apiUrl = builder.apiUrl;
        this.isJson = builder.isJson;
        this.bodyString = builder.bodyString;
        this.method = builder.method;
    }

    /*普通Http请求*/
    public void request(HttpObserver httpObserver) {
        this.httpObserver = httpObserver;
        if (httpObserver == null) {
            throw new NullPointerException("HttpObserver must not null!");
        } else {
            doRequest();
        }
    }

    /*上传文件请求*/
    public void upload(UploadObserver uploadCallback) {
        this.uploadCallback = uploadCallback;
        if (uploadCallback == null) {
            throw new NullPointerException("UploadObserver must not null!");
        } else {
            doUpload();
        }
    }

    /*执行请求*/
    private void doRequest() {

        /*设置请求唯一标识*/
        httpObserver.setTag(TextUtils.isEmpty(tag) ? disposeApiUrl() : tag);

        /*header处理*/
        disposeHeader();

        /*Parameter处理*/
        disposeParameter();

        /*请求方式处理*/
        Observable apiObservable = disposeApiObservable();

        /* 被观察者 httpObservable */
        HttpObservable httpObservable = new HttpObservable.Builder(apiObservable)
                .baseObserver(httpObserver)
                .lifecycleProvider(lifecycle)
                .activityEvent(activityEvent)
                .fragmentEvent(fragmentEvent)
                .build();
        /* 观察者  httpObserver */
        /*设置监听*/
        httpObservable.observe().subscribe(httpObserver);

    }

    /*执行文件上传*/
    private void doUpload() {

        /*设置请求唯一标识*/
        uploadCallback.setTag(TextUtils.isEmpty(tag) ? disposeApiUrl() : tag);

        /*header处理*/
        disposeHeader();

        /*Parameter处理*/
        disposeParameter();

        /*处理文件集合*/
        List<MultipartBody.Part> fileList = new ArrayList<>();
        if (fileMap != null && fileMap.size() > 0) {
            int size = fileMap.size();
            int index = 1;
            File file;
            RequestBody requestBody;
            for (String key : fileMap.keySet()) {
                file = fileMap.get(key);
                requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                MultipartBody.Part part = MultipartBody.Part.createFormData(key, file.getName(), new UploadRequestBody(requestBody, file, index, size, uploadCallback));
                fileList.add(part);
                index++;
            }
        }

        /*请求处理*/
        Observable apiObservable = RetrofitUtils.get().getRetrofit(getBaseUrl(), header).create(Api.class).upload(disposeApiUrl(), parameter, header, fileList);

        /* 被观察者 httpObservable */
        HttpObservable httpObservable = new HttpObservable.Builder(apiObservable)
                .baseObserver(uploadCallback)
                .lifecycleProvider(lifecycle)
                .activityEvent(activityEvent)
                .fragmentEvent(fragmentEvent)
                .build();
        /* 观察者  uploadCallback */
        /*设置监听*/
        httpObservable.observe().subscribe(uploadCallback);

    }

    /*获取基础URL*/
    private String getBaseUrl() {
        //如果没有重新指定URL则是用默认配置
        return TextUtils.isEmpty(baseUrl) ? Configure.get().getBaseUrl() : baseUrl;
    }

    /*ApiUrl处理*/
    private String disposeApiUrl() {
        return TextUtils.isEmpty(apiUrl) ? "" : apiUrl;
    }

    /*处理Header*/
    private void disposeHeader() {

        /*header空处理*/
        if (header == null) {
            header = new TreeMap<>();
        }

        //添加基础 Header
        Map<String, Object> baseHeader = Configure.get().getBaseHeader();
        if (baseHeader != null && baseHeader.size() > 0) {
            header.putAll(baseHeader);
        }

        if (!header.isEmpty()) {
            //处理header中文或者换行符出错问题
            for (String key : header.keySet()) {
                header.put(key, RequestUtils.getHeaderValueEncoded(header.get(key)));
            }
        }

    }

    /*处理 Parameter*/
    private void disposeParameter() {

        /*空处理*/
        if (parameter == null) {
            parameter = new TreeMap<>();
        }

        //添加基础 Parameter
        Map<String, Object> baseParameter = Configure.get().getBaseParameter();
        if (baseParameter != null && baseParameter.size() > 0) {
            parameter.putAll(baseParameter);
        }
    }

    /*处理ApiObservable*/
    private Observable disposeApiObservable() {

        Observable apiObservable = null;

        /*是否JSON格式提交参数*/
        boolean hasBodyString = !TextUtils.isEmpty(bodyString);
        RequestBody requestBody = null;
        if (hasBodyString) {
            String mediaType = isJson ? "application/json; charset=utf-8" : "text/plain;charset=utf-8";
            requestBody = RequestBody.create(okhttp3.MediaType.parse(mediaType), bodyString);
        }

        /*Api接口*/
        Api apiService = RetrofitUtils.get().getRetrofit(getBaseUrl(), header).create(Api.class);
        /*未指定默认POST*/
        if (method == null) method = Method.POST;

        switch (method) {
            case GET:
                apiObservable = apiService.get(disposeApiUrl(), parameter, header);
                break;
            case POST:
                if (hasBodyString)
                    apiObservable = apiService.post(disposeApiUrl(), requestBody, header);
                else
                    apiObservable = apiService.post(disposeApiUrl(), parameter, header);
                break;
            case DELETE:
                apiObservable = apiService.delete(disposeApiUrl(), parameter, header);
                break;
            case PUT:
                apiObservable = apiService.put(disposeApiUrl(), parameter, header);
                break;
        }
        return apiObservable;
    }

    /**
     * Configure配置
     */
    public static final class Configure {

        /*请求基础路径*/
        String baseUrl;
        /*超时时长*/
        long timeout;
        /*时间单位*/
        TimeUnit timeUnit;
        /*全局上下文*/
        Context context;
        /*全局Handler*/
        Handler handler;
        /*请求参数*/
        Map<String, Object> parameter;
        /*header*/
        Map<String, Object> header;
        /*是否显示Log*/
        boolean showLog;


        public static Configure get() {
            return Configure.Holder.holder;
        }

        private static class Holder {
            private static Configure holder = new Configure();
        }

        private Configure() {
            timeout = 60;//默认60秒
            timeUnit = TimeUnit.SECONDS;//默认秒
            showLog = true;//默认打印LOG
        }

        /*请求基础路径*/
        public RetrofitHttp.Configure baseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
            return this;
        }

        public String getBaseUrl() {
            return baseUrl;
        }

        /*基础参数*/
        public RetrofitHttp.Configure baseParameter(Map<String, Object> parameter) {
            this.parameter = parameter;
            return this;
        }

        public Map<String, Object> getBaseParameter() {
            return parameter;
        }

        /*基础Header*/
        public RetrofitHttp.Configure baseHeader(Map<String, Object> header) {
            this.header = header;
            return this;
        }

        public Map<String, Object> getBaseHeader() {
            return header;
        }

        /*超时时长*/
        public RetrofitHttp.Configure timeout(long timeout) {
            this.timeout = timeout;
            return this;
        }

        public long getTimeout() {
            return timeout;
        }

        /*是否显示LOG*/
        public RetrofitHttp.Configure showLog(boolean showLog) {
            this.showLog = showLog;
            return this;
        }

        public boolean isShowLog() {
            return showLog;
        }

        /*时间单位*/
        public RetrofitHttp.Configure timeUnit(TimeUnit timeUnit) {
            this.timeUnit = timeUnit;
            return this;
        }

        public TimeUnit getTimeUnit() {
            return timeUnit;
        }

        /*Handler*/
        public Handler getHandler() {
            return handler;
        }

        /*Context*/
        public Context getContext() {
            return context;
        }

        /*初始化全局上下文*/
        public RetrofitHttp.Configure init(Application app) {
            this.context = app.getApplicationContext();
            this.handler = new Handler(Looper.getMainLooper());
            return this;
        }

    }

    /**
     * Builder
     * 构造Request所需参数,按需设置
     */
    public static class Builder implements BridgeLifeCycleListener {
        /*请求方式*/
        Method method;
        /*请求参数*/
        Map<String, Object> parameter;
        /*header*/
        Map<String, Object> header;
        /*LifecycleProvider*/
        LifecycleProvider lifecycle;
        /*ActivityEvent*/
        ActivityEvent activityEvent;
        /*FragmentEvent*/
        FragmentEvent fragmentEvent;
        /*标识请求的TAG*/
        String tag;
        /*文件map*/
        Map<String, File> fileMap;
        /*基础URL*/
        String baseUrl;
        /*apiUrl*/
        String apiUrl;
        /*String参数*/
        String bodyString;
        /*是否强制JSON格式*/
        boolean isJson;
        private Builder instance;

        public Builder getInstanc() {
            if (instance == null) {
                synchronized (RetrofitHttp.class) {
                    if (instance == null) {
                        instance = new Builder();
                    }
                }
            }
            return instance;
        }

        /*GET*/
        public RetrofitHttp.Builder get() {
            this.method = Method.GET;
            return this;
        }

        /*POST*/
        public RetrofitHttp.Builder post() {
            this.method = Method.POST;
            return this;
        }

        /*DELETE*/
        public RetrofitHttp.Builder delete() {
            this.method = Method.DELETE;
            return this;
        }

        /*PUT*/
        public RetrofitHttp.Builder put() {
            this.method = Method.PUT;
            return this;
        }

        /*基础URL*/
        public RetrofitHttp.Builder baseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
            return this;
        }

        /*API URL*/
        public RetrofitHttp.Builder apiUrl(@NonNull String apiUrl) {
            this.apiUrl = apiUrl;
            return this;
        }

        /* 增加 Parameter 不断叠加参数 包括基础参数 */
        public RetrofitHttp.Builder addParameter(Map<String, Object> parameter) {
            if (this.parameter == null) {
                this.parameter = new TreeMap<>();
            }
            this.parameter.putAll(parameter);
            return this;
        }

        /* 增加 Parameter 不断叠加参数 包括基础参数 */
        public RetrofitHttp.Builder addParameter(String key, Object parameter) {
            if (this.parameter == null) {
                this.parameter = new TreeMap<>();
            }
            this.parameter.put(key, parameter);
            return this;
        }

        /*设置 Parameter 会覆盖 Parameter 包括基础参数*/
        public RetrofitHttp.Builder setParameter(Map<String, Object> parameter) {
            this.parameter = parameter;
            return this;
        }

        /* 设置String 类型参数  覆盖之前设置  isJson:是否强制JSON格式    bodyString设置后Parameter则无效 */
        public RetrofitHttp.Builder setBodyString(String bodyString, boolean isJson) {
            this.isJson = isJson;
            this.bodyString = bodyString;
            return this;
        }

        /* 增加 Header 不断叠加 Header 包括基础 Header */
        public RetrofitHttp.Builder addHeader(String key, Object header) {
            if (this.header == null) {
                this.header = new TreeMap<>();
            }
            this.header.put(key, header);
            return this;
        }

        /* 增加 Header 不断叠加 Header 包括基础 Header */
        public RetrofitHttp.Builder addHeader(Map<String, Object> header) {
            if (this.header == null) {
                this.header = new TreeMap<>();
            }
            this.header.putAll(header);
            return this;
        }

        /*设置 Header 会覆盖 Header 包括基础参数*/
        public RetrofitHttp.Builder setHeader(Map<String, Object> header) {
            this.header = header;
            return this;
        }

        /*LifecycleProvider*/
        public RetrofitHttp.Builder lifecycle(LifecycleProvider lifecycle) {
            this.lifecycle = lifecycle;
            return this;
        }

        /*ActivityEvent*/
        public RetrofitHttp.Builder activityEvent(ActivityEvent activityEvent) {
            this.activityEvent = activityEvent;
            return this;
        }

        /*FragmentEvent*/
        public RetrofitHttp.Builder fragmentEvent(FragmentEvent fragmentEvent) {
            this.fragmentEvent = fragmentEvent;
            return this;
        }

        /*tag*/
        public RetrofitHttp.Builder tag(String tag) {
            this.tag = tag;
            return this;
        }

        /*文件集合*/
        public RetrofitHttp.Builder file(Map<String, File> file) {
            this.fileMap = file;
            return this;
        }

        /*一个Key对应多个文件*/
        public RetrofitHttp.Builder file(String key, List<File> fileList) {
            if (fileMap == null) {
                fileMap = new IdentityHashMap();
            }
            if (fileList != null && fileList.size() > 0) {
                for (File file : fileList) {
                    fileMap.put(new String(key), file);
                }
            }
            return this;
        }

        public RetrofitHttp.Builder clear() {
            this.method = Method.POST;
            this.parameter = null;
            this.header = null;
            this.lifecycle = null;
            this.activityEvent = null;
            this.fragmentEvent = null;
            this.tag = "";
            this.fileMap = null;
            this.apiUrl = "";
            this.bodyString = "";
            this.isJson = false;
            this.instance = null;
            return this;
        }

        public RetrofitHttp build() {
            return new RetrofitHttp(this);
        }


        @Override
        public void initOnApplicationCreate(Context context) {

        }

        @Override
        public void clearOnApplicationQuit() {
            clear();
            RequestManagerImpl.getInstance().cancelAll();
        }
    }
}
/**
 * Api接口
 * <p>
 * Data:2018/12/18
 *
 * @author yong
 */
public interface Api {

    /**
     * GET 请求
     *
     * @param url       api接口url
     * @param parameter 请求参数map
     * @param header    请求头map
     * @return
     */
    @GET
    Observable<JsonElement> get(@Url String url, @QueryMap Map<String, Object> parameter, @HeaderMap Map<String, Object> header);

    /**
     * POST 请求
     *
     * @param url       api接口url
     * @param parameter 请求参数map
     * @param header    请求头map
     * @return
     */
    @FormUrlEncoded
    @POST
    Observable<JsonElement> post(@Url String url, @FieldMap Map<String, Object> parameter, @HeaderMap Map<String, Object> header);

    /**
     * @param requestBody 用于String/JSON格式数据
     */
    @POST
    Observable<JsonElement> post(@Url String url, @Body RequestBody requestBody, @HeaderMap Map<String, Object> header);

    /**
     * DELETE 请求
     *
     * @param url       api接口url
     * @param parameter 请求参数map
     * @param header    请求头map
     * @return
     */
    @DELETE
    Observable<JsonElement> delete(@Url String url, @QueryMap Map<String, Object> parameter, @HeaderMap Map<String, Object> header);


    /**
     * PUT 请求
     *
     * @param url       api接口url
     * @param parameter 请求参数map
     * @param header    请求头map
     * @return
     */
    @FormUrlEncoded
    @PUT
    Observable<JsonElement> put(@Url String url, @FieldMap Map<String, Object> parameter, @HeaderMap Map<String, Object> header);

    /**
     * 多文件上传
     *
     * @param url       api接口url
     * @param parameter 请求接口参数
     * @param header    请求头map
     * @param fileList  文件列表
     * @return
     * @Multipart 文件上传注解 multipart/form-data
     */
    @Multipart
    @POST
    Observable<JsonElement> upload(@Url String url, @PartMap Map<String, Object> parameter, @HeaderMap Map<String, Object> header, @Part List<MultipartBody.Part> fileList);

    /**
     * 断点续传下载
     *
     * @param range 断点下载范围 bytes= start - end
     * @param url   下载地址
     * @return
     * @Streaming 防止内容写入内存, 大文件通过此注解避免OOM
     */
    @Streaming
    @GET
    Observable<ResponseBody> download(@Header("RANGE") String range, @Url String url);

}

4.Bridge层抽象

BridgeFactory用来统一管理基础功能,类似本地服务的实现原理。 实现了文件,网络,安全等等管理类的实现,并保存了各类管理类的引用。业务层或者上层调用底层实现时,通过BridgeFactory去访问,而不是直接的调。

/**
 * <中间连接层>
 * Data:2018/12/18
 *
 * @author yong
 */
public class BridgeFactory {

    private static BridgeFactory model;

    private HashMap<String, Object> mBridges;

    private BridgeFactory() {
        mBridges = new HashMap<String, Object>();
    }

    public static void init(Application application) {
        model = new BridgeFactory();
        model.iniLocalFileStorageManager();
        model.initPreferenceManager();
        model.initSecurityManager();
        model.initUserSession();
        model.initOkHttpManager(application);
    }

    public static void destroy() {
        model.mBridges = null;
        model = null;
    }

    /**
     * 初始化本地存储路径管理类
     */
    private void iniLocalFileStorageManager() {
        LocalFileStorageManager localFileStorageManager = new LocalFileStorageManager();
        model.mBridges.put(Bridges.LOCAL_FILE_STORAGE, localFileStorageManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(localFileStorageManager);
    }

    /**
     * 初始化SharedPreference管理类
     */
    private void initPreferenceManager() {
        SharedPrefManager sharedPrefManager = new SharedPrefManager();
        model.mBridges.put(Bridges.SHARED_PREFERENCE, sharedPrefManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(sharedPrefManager);
    }

    /**
     * 网络请求管理类
     */
    private void initOkHttpManager(Application application) {
        RetrofitHttp.Configure.get().baseUrl(UrlConstans.SERVER).init(application);
        RetrofitHttp.Builder builder = new RetrofitHttp.Builder().getInstanc();
        model.mBridges.put(Bridges.HTTP, builder);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(builder);
    }

    /**
     * 初始化安全模块
     */
    private void initSecurityManager() {
        SecurityManager securityManager = new SecurityManager();
        model.mBridges.put(Bridges.SECURITY, securityManager);
        BridgeLifeCycleSetKeeper.getInstance().trustBridgeLifeCycle(securityManager);
    }

    /**
     * 初始化用户信息模块
     */
    private void initUserSession() {
    }

    /**
     * 通过bridgeKey {@link Bridges}来获取对应的Bridge模块
     *
     * @param bridgeKey {@link Bridges}
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <V extends Object> V getBridge(String bridgeKey) {
        final Object bridge = model.mBridges.get(bridgeKey);
        if (bridge == null) {
            throw new NullPointerException("-no defined bridge-");
        }
        return (V) bridge;
    }
}

BridgeLifeCycleListener 接口,实现各个底层功能管理类的统一初始化跟销毁工作,保持跟app的生命周期一致。

/**
 * 如果Bridge层的生命周期和App的生命周期相关(在Application
 * onCreate的时候初始化,在用户双击back键退出),则实现此接口,届时统一初始化和销毁
 * Data:2018/12/18
 *
 * @author yong
 */
public interface BridgeLifeCycleListener {
    void initOnApplicationCreate(Context context);

    void clearOnApplicationQuit();
}

5.多页面交互

EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。优点是开销小,代码更优雅,以及将发送者和接收者解耦。

EventBus.getDefault().register(this);//订阅事件

EventBus.getDefault().post(object);//发布事件

EventBus.getDefault().unregister(this);//取消订阅

Demo下载地址:https://download.csdn.net/download/qq_39735504/10861424

MVP模式封装框架地址:https://github.com/AgnoiY/MvpLibrary

注意:Demo中提供的登录接口返回数据类型错误,请不要使用,断点下载的没有实现的

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值