Android MVP 架构设计 (一)

Model–View–Presenter (MVP) 源于 Model–View–Controller (MVC) 的结构设计模式,它是用于展示层(Presentation)的结构。

MVP 中的 Presenter 是 “中间人”角色,它的功能是在 Model–View–Presenter 三者中起到连接和协作的作用。程序中的大部分的逻辑都应该在 Presenter 中实现。

  • Model 定义了数据的访问接口。例如之前文章 《App 组件化/模块化之路——Repository 模式》 就介绍了使用 Repository 实现数据访问的一种方式。
  • View 定义了展示数据的接口,以及转发用户的指令
  • Presenter 是连接 Model 与 View 的桥梁,是它们的协作者。

一、首先创建view 和 model接口

/**
 * 定义基础UI逻辑
 */
public interface IView {
    //定义初始化ui接口
    void initUI();
    //定义loading加载接口
    void showLoading();
    //显示数据接口
    void showListViewData(List<News> listData);

}
/**
 * 定义数据处理逻辑
 */
public interface IModel {

    //读取数据接口
    void loadData(OnLoadListener onLoadListener);

     //内部接口用于实现回调
    interface  OnLoadListener{
        void complete(List<News>listData);
    }

}

其次,在创建presenter实现view 和model 的连接 :


public class IPresenter<T extends IView> {

    //引入view实现
    IView iView ;
    //引入model实现
    IModel iModel = new NewsImpl();

    public IPresenter(T iView){
        this.iView = iView ;
    }

    public void fetch(){
        if(iView != null){
            iView.initUI();
            iView.showLoading();
        }
        if(iModel!= null){
            iModel.loadData(new IModel.OnLoadListener() {
                @Override
                public void complete(List<News> listData) {
                    if(iView != null){
                        iView.showListViewData(listData);
                    }
                }
            });
        }
    }
}

这里需要有一个列表数据加载的实现:

public class NewsImpl implements IModel {
    @Override
    public void loadData(OnLoadListener onLoadListener) {
        List<News> list = new ArrayList<News>();

        list.add(new News("http://pic3.nipic.com/20090527/1242397_102231006_2.jpg","科技图片111"));
        list.add(new News("http://pic29.nipic.com/20130601/12122227_123051482000_2.jpg","风景图片111"));
        list.add(new News("http://t8.baidu.com/it/u=3660968530,985748925&fm=191&app=48&wm=1,17,90,45,20,7&wmo=0,0&n=0&g=0n&f=JPEG?sec=1853310920&t=9b4f100f0eedfe853fad24a58a4e1ad7","图片2222"));
        list.add(new News("http://pic31.nipic.com/20130722/12473387_075510736124_2.jpg","图片33333"));
        list.add(new News("http://pic3.nipic.com/20090702/918855_174429094_2.jpg","图片4444"));
        list.add(new News("http://img.yanj.cn/store/goods/3488/3488_909a42564c7d2806ef3f87c4c5fe6029.jpg_max.jpg","图片5555"));

        onLoadListener.complete(list);
    }
}

我们实现了一个简单的listviewactivity,布局和adapter就不展示了,在activity实现Iview,代码如下:


public class MainActivity extends AppCompatActivity implements IView {

    ListView listV ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开始实现业务逻辑,条用presenter实现
        new IPresenter<>(this).fetch();
    }

    @Override
    public void initUI() {
        //初始化ui接口实现
        listV = (ListView) findViewById(R.id.list_v);
    }

    @Override
    public void showLoading() {
        //loading加载接口实现
        Toast.makeText(this,"加载中...",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showListViewData(List<News> listData) {
        //数据加载完成回调处理
        NewAdapter adapter = new NewAdapter(this,listData);
        listV.setAdapter(adapter);
    }
}

这样看起来代码很简洁,也很清晰,这就是一个简单的mpv架构模式的代码。

二、但是这样的代码在实际开发中还是会存在问题的,比如就有可能需要写很多这样的view-model-presenter,也有可能回引起activity内存泄露,所以在这里需要先加入软引用,优化泄露问题,首先修改Ipresenter:


public class IPresenter<T extends IView> {

    WeakReference<T> viewRef ;

    //引入view实现
    IView iView ;
    //引入model实现
    IModel iModel = new NewsImpl();

    public IPresenter(){
//        this.iView = iView ;
    }

    //绑定
    public void attachView(T view){
        viewRef = new WeakReference<>(view);
    }
    //解绑
    public void datachView(){
        viewRef.clear();
    }

    public void fetch(){
        if(viewRef.get() != null){
            viewRef.get().initUI();
            viewRef.get().showLoading();
        }
        if(iModel!= null){
            iModel.loadData(new IModel.OnLoadListener() {
                @Override
                public void complete(List<News> listData) {
                    if(viewRef.get() != null){
                        viewRef.get().showListViewData(listData);
                    }
                }
            });
        }
    }
}

activity修改:

 IPresenter iPresenter ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开始实现业务逻辑,条用presenter实现
//       new IPresenter<>(this).fetch();
        iPresenter = new IPresenter();
        iPresenter.attachView(this);
        iPresenter.fetch();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        iPresenter.datachView();
    }

三、这样虽然避免了activity内存泄漏问题,但是后面所有的activity view 和 presenter进行绑定和解绑,冗余开发太多,所以这里可以将activity 和  ipresenter 向上抽一层:
抽取一个BaseActivity:

public abstract class BaseActivity<V , T extends IBasePresenter<V>> extends AppCompatActivity {

    //表示层的引用
    public T iPresenter ;

    protected   abstract  T createPresenter();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        iPresenter = createPresenter();
        iPresenter.attachView((V)this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        iPresenter.datachView();
    }
}

抽取一个BasePresenter:

public class IBasePresenter<T > {

    WeakReference<T> viewRef ;

    //绑定view
    public void attachView(T view){
        viewRef = new WeakReference<>(view);
    }
    //解绑view
    public void datachView(){
        viewRef.clear();
    }

}

那么activity需要修改为:


public class MainActivity extends BaseActivity<IView , IPresenter<IView>> implements IView {

    ListView listV ;
    @Override
    protected IPresenter<IView> createPresenter() {
        return new IPresenter<>();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开始实现业务逻辑,调用presenter实现
//       new IPresenter<>(this).fetch();
//        iPresenter = new IPresenter();
//        iPresenter.attachView(this);
        iPresenter.fetch();
    }


    @Override
    public void initUI() {
        //初始化ui接口实现
        listV = (ListView) findViewById(R.id.list_v);
    }

    @Override
    public void showLoading() {
        //loading加载接口实现
        Toast.makeText(this,"加载中...",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showListViewData(List<News> listData) {
        //数据加载完成回调处理
        NewAdapter adapter = new NewAdapter(this,listData);
        listV.setAdapter(adapter);
    }
}

IPresenter修改为:


public class IPresenter<T extends IView> extends IBasePresenter<T> {


    //引入view实现
    IView iView ;
    //引入model实现
    IModel iModel = new NewsImpl();

    public IPresenter(){
//        this.iView = iView ;
    }


    public void fetch(){
        if(viewRef.get() != null){
            viewRef.get().initUI();
            viewRef.get().showLoading();
        }
        if(iModel!= null){
            iModel.loadData(new IModel.OnLoadListener() {
                @Override
                public void complete(List<News> listData) {
                    if(viewRef.get() != null){
                        viewRef.get().showListViewData(listData);
                    }
                }
            });
        }
    }
}

此时即完成mvp的架构抽取。

代码1:https://download.csdn.net/download/ssdate/11058371

代码2:https://download.csdn.net/download/ssdate/11060190

也可以移步至:https://gitee.com/ssdate/Android-developer-Study/tree/master/MvpDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值