玄机随录

MVP架构---基本使用篇

2020-03-19  本文已影响0人  大苏打6815

熟练用于MVP架构者这篇可以跳过

自己工作当中,涉及到APP开发的部分并不多,MVP+Retrofit+Rxjava这种模式其实在两年前就用的很多了,自己也利用WanAndroid写过一个这种架构模式的APP,而不是像以前MVC一把梭,总体来说好处多。除了本章讲MVP项目模式之外,还会涉及到谷歌最新推出的jetpack技术,作为记录自己学习的一个过程,如果有缘看到这篇文章,写的不妥之处也可以指出来。

MVP VS MVC

MVP想对比MVC,其实要多绕几个弯,性能上执行速度稍微有一点点影响,但是对于代码解耦性是非常强的。MVC以前都可以写在一个Activity里面,V就是Activity视图层,M是网络加载层也能写在Activity里,C层控制器比如setAdapter都能写在同一个Activity,如果业务量多 了,代码维护起来,会很困难,MVP会拆分出不同的模块,使得层次更清晰,当然对应的接口也会相应的增多。

Jetpack

是为了让安卓开发有自己完成的标准,避免大家开发东西的时候,都是用自己的内容,这样子做的好处,不同的APP(比如换家公司接手别人的APP)里面的东西是千奇百怪。没有一个标准,所以在18年在google开发者大会上面就发布了这个概念。https://developer.android.google.cn/jetpack?hl=zh_cn里面分了很多模块,个人比较对架构模块感兴趣,里面有数据绑定,Lifecycles,LiveData,ViewModel,WorkManager等等。这些东西到时候都会集成在MVP里面,也会涉及到原理,后续会分章节简单介绍。

把UI逻辑抽象成VIEW接口,把业务逻辑抽象层Present接口,Moudule还是原来的model

image.png
工程视图
image.png

我们假设有这个场景,就加载一个listview(懒得写RecycleView了),item就是左边一张图片,右边上下两行textview,纯粹用MVP怎样去加载。
这个item的类型我们就叫做Girl,我们在bean包里面新建一个Girl

package com.mvp.lianxi.com.bean;
public class Girl{
    public int icon;
    public String like;
    public String style;

    public Girl() {
    }
    public Girl(int icon, String like, String style) {
        super();
        this.icon = icon;
        this.like = like;
        this.style = style;
    }
    public int getIcon() {
        return icon;
    }
    public void setIcon(int icon) {
        this.icon = icon;
    }
    public String getLike() {
        return like;
    }
    public void setLike(String like) {
        this.like = like;
    }
    public String getStyle() {
        return style;
    }
    public void setStyle(String style) {
        this.style = style;
    }
}

接下来我们写一个视图层view层,标示这个类的view最终要显示什么东西,同时写一个base视图层,这个base视图层是所有View到时候有的一个共性的东西,比如showerrormessage,方便后面扩展

public interface IBaseView {
    void showErrorMessage(String msg);
}

然后我们写当前这个V视图层要做的东西,肯定是展示,可能展示一张图片,可能有进度条,可能获取视频资料,并且我们还要继承这个IBaseView

public interface IGirlView extends IBaseView{
    //显示图片(回调函数)
    void showGirlView(List<Girl> girls);
    //加载进度条

    //获取视频资料
}
到了这里我们的View层就写完了,下面写Model层,也叫数据层,网络请求的

首先我们在model包里面定义一个叫IGirlModel的接口,这个接口里面的方式是表示他要去做什么事情,肯定是去加载数据。

public interface IGirlModel{
    void loadGirlData(OnLoadListener onLoadListener);
    interface  OnLoadListener{
        void onComplete(List<Girl>girls);
    }
}

为什么这里要写一个内部接口?你loadGirlData去做加载了数据之后,这些数据是有用的,肯定要回传过来,我们要求回传的目标就是一些列Girl类型的集合,拿到这样的数据后才能去给人家从而展示。
然后我们新建一个叫GirlModel的类,去实现这个IGirl接口真正意义上的去做事(模拟加载数据)

public class GirlModel implements IGirlModel{
    @Override
    public void loadGirlData(OnLoadListener onLoadListener){

        //这里进行各种网络请求,现在没有依赖其他网络库,我模拟一些数据,就当网络请求了
        //然后通过接口回调的方式回传
        List<Girl> data = new ArrayList<>();
        data.add(new Girl(R.drawable.f1, "一星", "****"));
        data.add(new Girl(R.drawable.f2, "一星", "****"));
        data.add(new Girl(R.drawable.f3, "一星", "****"));
        data.add(new Girl(R.drawable.f4, "一星", "****"));
        data.add(new Girl(R.drawable.f5, "一星", "****"));
        data.add(new Girl(R.drawable.f6, "一星", "****"));
        data.add(new Girl(R.drawable.f7, "一星", "****"));
        data.add(new Girl(R.drawable.f8, "一星", "****"));
        data.add(new Girl(R.drawable.f9, "一星", "****"));
        data.add(new Girl(R.drawable.f10, "一星", "****"));

        onLoadListener.onComplete(data);
    }
}
到了这里我们的Model层就写完了,下面Present层,也叫交互层,要联系V和M的。

现在我们新建一个基础P层我们叫BasePresent,所有的present类都要去继承这个Basepresent,因为这个presetn到时候要attachview和detachview去获取和及时释放对象的。不可能每个Activity里面都手动调用一遍这个方法。所以要写一个BasePresenter这个基类。要注意的就是代码里面的引用最好用WeakReference弱引用。关于弱引用的好处可以搜集一下资料。这里用到了泛型,本来<>里面是<IGirlView>,目的是为了持有这个View我们才能去获取和释放对象。这个对象不一定是IGielView,可能会有很多种xxxView,因此我们用泛型来代替。如果写死了,这就没法用了。这个attachview(T view)和detachview()目的是要用在BaseAcvitiy这种基类里面的。

public class BasePresenter <T extends IBaseView>{
    WeakReference<T>iGirlView;
    public void attachView(T view){
        iGirlView=new WeakReference<>(view);
    }

    public void detachview(){
        if(iGirlView!=null){
            iGirlView.clear();
            iGirlView=null;
        }
    }
}

现在我们看真正的GirlPresenter要做的事情,肯定是要去继承BasePresenter的,这里注意了,上面的BasePresenter已经持有了左边的VIEW了啊,既然GirlPresenter要继承BasePresenter的话那GirlPresenter也持有了左边的View。因此这个GirlPresenter所需要的就是把右边的MODEL给联系起来

public class GirlPresenter<T extends IGirlView> extends BasePresenter<T>{
    //持有右边的MODEL
    IGirlModel iGirlModel=new GirlModel();

    //执行UI逻辑
    public void fetch(){
        if(iGirlView.get()!=null&&iGirlModel!=null){
            iGirlModel.loadGirlData(new IGirlModel.OnLoadListener(){
                @Override
                public void onComplete(List<Girl> girls){
                    //girls上面就是model来的数据
                    //再交给view
                    iGirlView.get().showGirlView(girls);
                }
            });
        }
    }
}
到了这里我们把P层写完了,这三者写完之后,我们需要通过Activity....去联系起来

上面讲到一个dettachview和attachview,我们完全可以把这两个逻辑写在BaseActivity里面,这样就不用在每个Activity的oncreat和ondestroey去调用,另外我们为了避免每次都在各种Activity...自己创建一个present,我们完全可以用抽象类,去写一个抽象方法,然后让子类去继承这个BaseActivity,就会复写这个方法,然后我们在这个方法里面写入具体产生present的逻辑就可以了,这样一来是很方便的。具体代码如下。

public abstract class BaseActivity<T extends BasePresenter,V extends IBaseView> extends AppCompatActivity{
    //持有表示层
    protected T presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        presenter=creatPresenter();
        presenter.attachView((V)this);
    }

    public abstract T creatPresenter();

    @Override
    protected void onDestroy(){
        super.onDestroy();
        presenter.detachview();
    }
}

BaseAvitiy两个泛型标示一个是持有了中间层,另外一个持有View层
现在我们新建一个Activity集成BaseActivity,中间层P帮我们把数据M数据也拿到了,直接V展示UI就行了。

public class MainActivity extends BaseActivity<GirlPresenter<IGirlView>, IGirlView>implements IGirlView{

    ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView=findViewById(R.id.listview);
        presenter.fetch();
    }

    @Override
    public GirlPresenter creatPresenter(){
        return new GirlPresenter();
    }

    @Override
    public void showGirlView(List<Girl> girls){
        Log.d("MainActivity", "girls:" + girls);
        //表示层就会把数据填到girls上
        listView.setAdapter(new GirlAdapter(this, girls));
    }

    @Override
    public void showErrorMessage(String msg){
    }

一个简单的MVP架构就搭建好了,个人认为从这个简单的写法更好理解MVP架构,当然,写法有很多,真实项目里面会写的更复杂写。目前很多公司大部分都是用的这种模式。下节继续分析在MVP模式下,一行代码切换网络加载框架
链接:https://pan.baidu.com/s/11OkQ5v1C7Su1_W7uOuF2bw
提取码:ttgb
复制这段内容后打开百度网盘手机App,操作更方便哦

上一篇下一篇

猜你喜欢

热点阅读