MVP在Android项目中的应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010872619/article/details/81384465

MVP模式简介
       简称:MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

模式特点
       MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
MVP模型

MVP在Android中的应用
       在Android项目中,V层对应于activity或者fragment,在整个模式中V层最薄,V层会实现一个接口,通过这个接口,回调P层传过来的数据,然后进行视图更新。

public class UserActivity extends BaseActivity<UserPresenter> implements UserView {

    @Bind(R.id.tv_name)
    TextView mTvName;
    @Bind(R.id.tv_gender)
    TextView mTvGender;

    @Override
    protected int onSetLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected UserPresenter createPresenter() {
        return new UserPresenter(mContext);
    }

    @Override
    public void initView() {
        //初始化一些UI
    }

    @Override
    protected void initData() {
        //请求用户数据
        mPresenter.getUserData(1100);
    }

    /**
     * 由MainPresenter回调过来的数据,然后更新UI
     *
     * @param userInfo
     */
    @Override
    public void setData(UserInfo userInfo) {
        //更新UI
        mTvName.setText(userInfo.getName());
        mTvGender.setText(userInfo.getGender());
    }

}
/**
 * @作者: TJ
 * @时间: 2018/7/23 16:56
 * @描述: Activity基类,MVP中的V层,主要设置视图相关
 */
public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements View.OnClickListener, BaseView {

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

    protected BaseActivity mContext;
    /**
     * presenter
     */
    protected P            mPresenter;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        //创建presenter并绑定view,这里默认创建一个Presenter,如果需要创建多个需要自己处理。
        mPresenter = createPresenter();
        if (mPresenter != null) mPresenter.attachView(this);
        setContentView(onSetLayoutId());
        init();
    }

    /**
     * 设置布局文件
     *
     * @return 返回布局文件资源Id
     */
    protected abstract int onSetLayoutId();

    /**
     * 创建Presenter
     *
     * @return 返回Presenter
     */
    protected abstract P createPresenter();


    /**
     * 初始化页面
     */
    protected void init() {
        initView();
        bindEvent();
        initData();
    }


    /**
     * 初始化view
     */
    public abstract void initView();


    /**
     * 绑定事件
     */
    public void bindEvent() {
    }

    /**
     * 初始化数据
     */
    protected void initData() {

    }

    @Override
    public void onClick(View v) {

    }

    /**
     * 显示一个Toast信息
     */
    @Override
    public void showToastMessage(String message) {
        if (message != null) {
            ToastUtils.showShort(message);
        }
    }

    @Override
    public void showToastMessage(int res) {
        if (res != 0) {
            ToastUtils.showShort(getString(res));
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        ButterKnife.unbind(this);
        if (mPresenter != null) {
            mPresenter.detachView();
            mPresenter = null;
        }
    }
}

       在V层创建一个Presenter,然后绑定View。在V层通过Presenter来调用Presenter中的一些方法,而在P层通过接口将数据回调给V层,这样实现了VP交互。

       Android中P层为自定义的一个Presenter类,连接V层和M层,主要处理业务以及逻辑相关的东西。在Presenter会创建一个Modle类即M层,将数据传给传给M层进行网络请求、数据处理,然后通过接口将M层返回的数据传递给P层。

/**
 * @作者: TJ
 * @时间: 2018/8/2 16:53
 * @描述: 用户相关业务以及逻辑,此类可以复用,只用于用户相关,可以扩充方法分别精选处理
 */
public class UserPresenter extends BasePresenter<UserView, UserModle> {

    public UserPresenter(Context context) {
        super(context);
    }

    @Override
    protected UserModle createModel() {
        return new UserModle();
    }


    /**
     * 获取数据
     *
     * @param id
     */
    public void getUserData(long id) {
        mModel.getUserData(id, new LzyCallback<UserInfo>() {
            @Override
            public void onNext(UserInfo userInfo) {
                mView.setData(userInfo);
            }
        });
    }
}
/**
 * @作者: TJ
 * @时间: 2018/4/11 11:53
 * @描述: Presenter基类,连接V层和M层,主要处理业务以及逻辑相关的东西,将相关数据传给M层进行网络请求、数据处理,然后将M层返回的数据传递给P层
 */
public abstract class BasePresenter<V extends BaseView, M extends BaseModel> {

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

    protected V       mView;
    protected M       mModel;
    protected Context mContext;

    public BasePresenter(Context context) {
        mContext = context;
    }

    public void attachView(V view) {
        mView = view;
        mModel = createModel();
        onViewAttach();
    }


    /**
     * 将Presenter与View解除 Presenter与Model解除
     */
    public void detachView() {
        mView = null;
        mModel = null;
        onViewDetach();
    }

    /**
     * 当View与Presenter绑定时回调,此时界面控件等均未初始化
     */
    protected void onViewAttach() {
    }


    /**
     * 当View与Presenter解除绑定时回调
     */
    protected void onViewDetach() {
    }

    /**
     * 创建model
     *
     * @return
     */
    protected abstract M createModel();

}

       Android中M层为自定义的Model类,以及服务器返回的数据类,主要获取数据以及处理数据,然后返回给P层。该类在Presenter中创建,直接调用Model中的方法,通过接口将数据返回给Presenter。

/**
 * @作者: TJ
 * @时间: 2018/8/2 16:49
 * @描述: 从Presenter传过来数据,然后进行网络请求以及对请求的数据处理等,此类可以复用,只要有相同的请求都可以复用
 */
public class UserModle extends BaseModel {

    public void getUserData(long id, LzyCallback<UserInfo> callback) {
//        Observable<HttpResult<List<UserInfo>>> observable = mApiService.getUserInfo(id);
//        applySchedulers(observable);
//        observable.subscribe(this.<HttpResult<List<UserInfo>>>newObserver(callback));
        //简化一下
        applySchedulers(mApiService.getUserInfo(id)).subscribe(newObserver(callback));
    }
}
/**
 * @作者: TJ
 * @时间: 2018/7/24 9:26
 * @描述: Model基类,MVP中M层,对应P层,主要获取数据以及处理数据,然后返回给P层
 */
public class BaseModel {

    public final String TAG = this.getClass().getSimpleName();
    protected       CompositeDisposable mCompositeDisposable;
    protected final RetrofitApiService  mApiService;


    public BaseModel() {
        //Presenter在创建Model对象的时候创建CompositeDisposable对象,在Presenter解除与View绑定的时候,取消所有的订阅。
        mCompositeDisposable = new CompositeDisposable();
        //初始化retrofit,给之后的网络请求做准备
        mApiService = RetrofitApi.getService();
    }


    //将每次的订阅操作进行封装,简化重复代码量,分割返回的数据
    public <T> Observable<T> applySchedulers(Observable<HttpResult<T>> o) {
        Observable<T> observable = o.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<HttpResult<T>, T>() {
                    @Override
                    public T apply(HttpResult<T> result) throws Exception {
                        return result.getData();
                    }
                });
        return observable;
    }

    /**
     * 创建观察者  这里对观察着过滤一次,过滤出我们想要的信息,错误的信息toast
     *
     * @param <T>
     * @return
     */
    public <T> Observer<T> newObserver(final LzyCallback callback) {
        return new Observer<T>() {

            @Override
            public void onError(Throwable e) {
                LogUtils.e(TAG, "newObserver-> onError: ---" + e.getMessage());
                callback.onError(e);
            }

            @Override
            public void onComplete() {
                LogUtils.e(TAG, "newObserver-> onComplete: ---");
                callback.onComplete();
            }

            @Override
            public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
                mCompositeDisposable.add(d);
            }

            @Override
            public void onNext(T t) {
                if (!mCompositeDisposable.isDisposed()) {
                    LogUtils.e(TAG, "newObserver-> onNext: ---");
                    callback.onNext(t);
                }
            }
        };
    }
}

代码:https://github.com/junlintian5233/rxjavaretrofitmvpdemo

猜你喜欢

转载自blog.csdn.net/u010872619/article/details/81384465