Android项目实战(1)搭建MVP框架

准备用MVP框架搭建一个自己的项目,之前的项目有用到过,但都是公司的同事搭建好的,现在自己搭建一个。
搭建之前先来了解一下MVP。
1、什么是MVP

M(Model)负责数据的请求,解析,过滤等数据操作。
V(View)负责处理UI,通常以Activity Fragment的形式出现。
P(Presenter)View Model中间件,交互的桥梁。

2、MVP的优点

分离了UI逻辑和业务逻辑,降低了耦合。
Activity只处理UI相关操作,代码变得更加简洁。
UI逻辑和业务逻辑抽象到接口中,方便阅读及维护。
把业务逻辑抽到Presenter中去,避免复杂业务逻辑造成的内存泄漏。

3、MVP与MVC的比较

MVP的优点:
1)复杂的逻辑处理放在presenter进行处理,减少了activity的臃肿。
2)M层与V层完全分离,修改V层不会影响M层,降低了耦合性。
3)可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。
3)P层与V层的交互是通过接口来进行的,便于单元测试。
MVP的缺点:
由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁,视图需要改变,一般presenter也需要跟着改变.

/******************************************************************************************************************/

MVC的优点:
1):分工明确,各司所职。
2):一定程度上降低了代码间的耦合性。
MVC的缺点:
1):随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。
2):视图和控制器间过于紧密的联系,妨碍了各自的重用。

搭建过程
创建基类
Android项目实战(1)搭建MVP框架_第1张图片
1.对View进行封装,主要处理显示加载框、请求成功、请求失败等操作

package com.lyw.modulemvp.base;
import android.content.Context;
/**
 * 功能描述:
 * Created on 2020/6/29.
 * @author lyw
 */

public interface IBaseView {

    /**
     * 显示加载框
     */
    void showLoading();

    /**
     * 隐藏加载框
     */
    void dismissLoading();

    /**
     * 空数据
     *
     * @param tag TAG
     */
    void onEmpty(Object tag);

    /**
     * 错误数据
     *
     * @param tag      TAG
     * @param errorMsg 错误信息
     */
    void onError(Object tag, String errorMsg);

    /**
     * 上下文
     *
     * @return context
     */
    Context getContext();
}

2.对Presenter封装 ,为了避免持有View的Presenter做耗时操作而引起的内存泄漏,我们的Presenter应该和宿主Activity/Fragment同创建、同销毁。

package com.lyw.modulemvp.base;

import android.content.Context;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 功能描述:
 * Created on 2020/6/29.
 * @author lyw
 */

public abstract class BasePresenter<M extends IBaseModel, V extends IBaseView> {

    private V mView;
    private M mModel;
    private WeakReference<V> weakReference;

    /**
     * 绑定View
     */
    @SuppressWarnings("unchecked")
    public void attachView(V view) {
        weakReference = new WeakReference<>(view);
        mView = (V) Proxy.newProxyInstance(
                view.getClass().getClassLoader(),
                view.getClass().getInterfaces(),
                new MvpViewHandler(weakReference.get()));
        if (this.mModel == null) {
            this.mModel = createModule();
        }
    }

    /**
     * 解绑View
     */
    public void detachView() {
        this.mModel = null;
        if (isViewAttached()) {
            weakReference.clear();
            weakReference = null;
        }
    }

    /**
     * 是否与View建立连接
     */
    protected boolean isViewAttached() {
        return weakReference != null && weakReference.get() != null;
    }

    protected V getView() {
        return mView;
    }

    protected M getModule() {
        return mModel;
    }

    protected Context getContext() {
        return getView().getContext();
    }

    protected void showLoading() {
        getView().showLoading();
    }

    protected void dismissLoading() {
        getView().dismissLoading();
    }


    /**
     * 通过该方法创建Module
     */
    protected abstract M createModule();

    /**
     * 初始化方法
     */
    public abstract void start();


    /**
     * View代理类  防止 页面关闭P异步操作调用V 方法 空指针问题
     */
    private class MvpViewHandler implements InvocationHandler {

        private IBaseView mvpView;

        MvpViewHandler(IBaseView mvpView) {
            this.mvpView = mvpView;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //如果V层没被销毁, 执行V层的方法.
            if (isViewAttached()) {
                return method.invoke(mvpView, args);
            } //P层不需要关注V层的返回值
            return null;
        }
    }
}

3、对Activity的封装,Fragment封装同理,通过泛型规定Presenter,并且暴露抽象方法createPresenter()给子类来创建Presenter,基类实现BaseView中的公共方法,减少子类代码的冗余。

package com.lyw.modulemvp.base;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;

/**
 * 功能描述:Mvp Activity基类
 * Created on 2020/6/29.
 * @author lyw
 */
public abstract class BaseMvpActivity<P extends BasePresenter> extends BaseActivity implements IBaseView {
    protected P presenter;
    private Context mContext;
    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建present
        presenter = createPresenter();
        if (presenter != null) {
            presenter.attachView(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (presenter != null) {
            presenter.detachView();
            presenter = null;
        }
    }
    @Override
    public void showLoading() {
        if (mLoadingLayout != null) {
            mLoadingLayout.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void dismissLoading() {
        if (mLoadingLayout != null) {
            mLoadingLayout.setVisibility(View.GONE);
        }
    }

    @Override
    public void onEmpty(Object tag) {

    }

    @Override
    public void onError(Object tag, String errorMsg) {

    }

    @Override
    public Context getContext() {
        return mContext;
    }
    /**
     * 创建Presenter
     */
    protected abstract P createPresenter();
}

子类的具体实现会在后面的demo完善,DEMO地址

你可能感兴趣的:(Android项目实战)