MVP模式学习

参考文档:

1:https://www.jianshu.com/p/fee58fe60a2d

 

1:MVP详解

1:简介

MVP全称是Model View Presenter。

M:业务模型;

V:用户界面;

P:主持者,Model和View之间的桥梁。

25021128-909fac1dbd247bbc.png

 

2:MVP核心思想

把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model类。

 

3:MVP的作用

1:分离视图逻辑和业务逻辑,降低耦合;

2:Activity只处理生命周期的任务,代码简洁;

3:视图逻辑和业务逻辑抽象到了View和Presenter中,提高阅读性;

4:Presenter被抽象成接口,可以有多种具体的实现;

5:业务逻辑在Presenter中,避免后台线程引用Activity导致内存泄漏;

 

2:MVP实现实例

1:添加契约&协议

public interface DownloaderContract {
    interface Model {
        //p层告诉M层,需要做什么事情
        void requestDownloader(ImageBean imageBean) throws Exception;
    }

    interface PresenterView {
        //View层告诉Presenter层做什么事情
        void requestDownloader(ImageBean imageBean);

        //Presenter层从Model层的结果返回,在通知View层
        void responseDownloaderReult(boolean isSuccess, ImageBean imageBean);
    }

}

2:定义数据model

public class ImageBean {

    //图片请求地址
    private String requestPath;

    //结果返回图片
    private Bitmap bitmap;

    public String getRequestPath() {
        return requestPath;
    }

    public void setRequestPath(String requestPath) {
        this.requestPath = requestPath;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }
}

3:发布层presenter的实现类

public class DownLoaderPresenter implements DownloaderContract.PresenterView {

    private WeakReference<DownloaderContract.PresenterView> view;
    private DownloaderEngine model;//处理事情的模型

    public DownLoaderPresenter(DownloaderContract.PresenterView view){
        this.view = new WeakReference<>(view);
        model = new DownloaderEngine(this);
    }

    @Override
    public void requestDownloader(ImageBean imageBean) {
        //接收到view层的指令,去完成某个需求
        try{
            model.requestDownloader(imageBean);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void responseDownloaderReult(final boolean isSuccess, final ImageBean imageBean) {
       ((Activity)view.get()).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                view.get().responseDownloaderReult(isSuccess, imageBean);
            }
        });
    }
}

4:发布层需用处理的功能模块

public class DownloaderEngine implements DownloaderContract.Model {

    private DownLoaderPresenter presenter;

    public DownloaderEngine(DownLoaderPresenter downLoaderPresenter) {
        this.presenter = downLoaderPresenter;
    }

    @Override
    public void requestDownloader(ImageBean imageBean) throws Exception {
        //p层让我做这个需求
        new Thread(new DownLoadr(imageBean)).start();
    }

    final class DownLoadr implements Runnable {

        private final ImageBean imageBean;

        public DownLoadr(ImageBean imageBean) {
            this.imageBean = imageBean;
        }

        @Override
        public void run() {
            try{
                URL url = new URL(imageBean.getRequestPath());
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setConnectTimeout(5000);
                httpURLConnection.setRequestMethod("GET");

                if(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
                    InputStream inputStream = httpURLConnection.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    showUi(Constant.SUCCESS, bitmap);
                }else{
                    showUi(Constant.ERROR, null);
                }

            }catch (Exception e){
                e.printStackTrace();
                showUi(Constant.ERROR,null);
            }
        }

        private void showUi(int error, Bitmap bitmap) {
            imageBean.setBitmap(bitmap);
            presenter.responseDownloaderReult(error == Constant.SUCCESS, imageBean);
        }
    }

}

5:数据处理完成后更新视图

public class MpvWorkModeActivity extends AppCompatActivity implements DownloaderContract.PresenterView {

    private ImageView imageView;
    private DownLoaderPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mpv_work_mode);

        imageView = findViewById(R.id.iv);
        presenter = new DownLoaderPresenter(this);
    }

    @Override
    public void requestDownloader(ImageBean imageBean) {
        if(presenter != null) presenter.requestDownloader(imageBean);
    }

    @Override
    public void responseDownloaderReult(boolean isSuccess, ImageBean imageBean) {
        Toast.makeText(this,isSuccess?"下载成功":"下载失败", Toast.LENGTH_SHORT).show();

        if(isSuccess && imageBean.getBitmap() != null){
            imageView.setImageBitmap(imageBean.getBitmap());
        }
    }

    public void down(View view) {
        ImageBean imageBean = new ImageBean();
        imageBean.setRequestPath(Constant.IMAGE_PATH);

        requestDownloader(imageBean);
    }
}

6:工具类的补充

public class Constant {

    //网络图片地址
    public static final String IMAGE_PATH = "https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png";
    //成功
    public static final int SUCCESS = 200;
    //失败
    public static final int ERROR = 404;
}

7:注意事项

以上代码中,使用到了弱引用,可以防止用户关闭activity导致的内存泄露问题