zoukankan      html  css  js  c++  java
  • Android MVP框架实现过程

    MVP框架实现过程

    目的:View层和Model层分离,中间由Presenter处理逻辑。

    Prester作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。这里我们只说明View和Presenter的交互, 
    Model与Presenter与前者大致相同,甚至可以直接略过接口直接使用,因此不再赘述。

    我们期望减少在Activity,Fragment类的容量,使View层专心View的实现,将逻辑由P层处理。

    即存在对View实现的V和对逻辑实现的P,V中调用P的方法处理逻辑,P调用V处理View变化。那么怎样将两者联系在一起?

    实现:

    1、建立联系

    如果想要在V中调用P的方法,只要在V中建立P的对象。即在V中,P p = new P(); 然后p.xx();

    此时只是V单向的含有P的引用,让p拥有v的引用。理所当然,我们通过p.attachView(this); 传递this参数, 
    使p对象拥有对应的v对象的引用。

    同时,不能忘记使用p.detachView(); 目的是保持P和V的生命周期一致,即在V销毁时,P逻辑上也失去效用,也应销毁, 
    防止由于P保持对V的引用,导致V无法销毁,内存溢出。

    注:对于内存溢出,我们可以在P中attchView()和detachView()具体实现中使用弱引用的方式,强化防止内存溢出。


    public class MvpView {
    
        private MvpPresenter presenter;
    
        public void onCreate(){
    
            presenter = new MvpPresenter();
    
            presenter.attachView(this);
        }
    
        public void onDestroy(){
    
            presenter.detachView();
        }
    }
    
    public class MvpPresenter {
    
        private WeakReference<MvpView> viewRef;
    
        public void attachView(MvpView view) {
            viewRef = new WeakReference<>(view);
        }
    
        public void detachView() {
            if (viewRef != null) {
                viewRef.clear();
                viewRef = null;
            }
        }
    
        public void xx() {}
    }
    

    但是这里远远没有结束,我们不能忽略xx()。也就是


    public void attachView(MvpView view) {
        viewRef = new WeakReference<>(view);
    }
    

    MvpView不能写死,因此需要使用接口,只是声明方法,无需关心方法的具体实现。(本人始终觉得接口最好用的在于分层后, 
    Coder只需先关注于一层的逻辑,而无需在几层之间来回切换)由于下面将接口和连接的实现分离,这里不重复给出源码。、

    2、实现复用(继承,泛型)

    由于并不是只有某个View代码需要分离,同时实现连接的共同方法可以复用,这里我们需要实现V和P建立联系的实现的复用。

    步骤有二,一是将不同View接口和实现连接的公共部分分离,公共部分抽离成父类,二是使得match的特定V和P相互联系。

    1)如果单纯的抽离成父类,这十分简单,只需要将上述的代码直接copy到工程的BaseActivity或者BaseFragment中, 
    或者单独隔离成继承Base类的MvpBase类。

    无疑我们采取单独隔离成继承Base类的MvpBase类的方式,既是因为实现逻辑的分离,同时并不是所有View逻辑都适合分离出, 
    也是因为为了下一步使得match的特定V和P相互联系。

    2)这时假设我们有Va和Vb,都继承MvpView;同时有Pa和Pb,也都继承MvpPresenter。很显然这样V父类中的实现无法知晓该返回 
    Pa或者Pb的对象,同样的MvpPresenter也只能对父类MvpView对象操作。

    自然而然我们想到了泛型,在父类中添加泛型,在类被使用时再被告知该返回哪个子类。由下文代码找到P中需要为泛型是接口IViewA。 
    而V需要泛型的为Presenter类。

    public class MvpViewA implements IViewA {
    
        private MvpPresenter presenter;
    
        public void onCreate(){
    
            presenter = new MvpPresenter();
    
            presenter.attachView(this);
        }
    
        public void onDestroy(){
    
            presenter.detachView();
        }
    
        public void doSomeInV(){}
    }
    

    public class MvpPresenter {
    
        private WeakReference<IViewA> viewRef;
    
        public void attachView(IViewA view) {
            viewRef = new WeakReference<>(view);
        }
    
        public void detachView() {
            if (viewRef != null) {
                viewRef.clear();
                viewRef = null;
            }
        }
    
        public void doSomeInP(){
            viewRef.doSomeInView()
        }
    }
    

    变为


    public abstract class MvpBasePresenter<V extends IMvpView> implements MvpPresenter<V> {
    
        private WeakReference<V> viewRef;
    
        @Override
        public void attachView(V view) {
            viewRef = new WeakReference<V>(view);
        }
    
        protected V getView() {
            return viewRef.get();
        }
        @Override
        public void detachView() {
            if (viewRef != null) {
                viewRef.clear();
                viewRef = null;
            }
        }
    }
    
    
    public abstract class MvpBaseView<P extends MvpPresenter> extends BaseView implements IMvpView {
        protected P presenter;
    
        protected abstract P createPresenter();
    
        protected void onCreate() {
            presenter = createPresenter();
    
            presenter.attachView(this);
        }
    
        protected void onDestroy() {
            presenter.detachView();
        }
    }
    

     厉害了 解耦更成功了一步。

  • 相关阅读:
    py3学习笔记0(入坑)
    为什么很多PHP文件最后都没有?>
    作业
    凯撒密码、GDP格式化输出、99乘法表
    作业4
    作业3
    turtle库基础练习
    作业2
    作业1
    编译原理有限自动机的构造与识别
  • 原文地址:https://www.cnblogs.com/cold-ice/p/6836155.html
Copyright © 2011-2022 走看看