可复用MVP架构搭建

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

Mvp想必做Android开发的同学多多少少都会接触一些,今天来分享下基础的MVP架构如何构建

Mvp核心思想:

mvp把activity中ui逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model还是原来的Model

优点:

1、activity职责更加明确,完成UI逻辑和使用哪一个表示层

2、代码结构清楚,更容易维护

3、方便单元测试

4、避免Activity的内存泄漏

View层的ui逻辑通过接口关联到表示层,表示层通过Model层的数据接口,实现对数据的操作,关键在于数据回调过程的处理和在构建MVP过程中防止内存泄漏,基础的mvp架构很简单,但是如果想要构建一个通用的架构,还是要费点心思。

由上图可以看出,mvp分层虽然代码相对于mvc复杂一些,但是可以应对频繁的需求变更,无论是View层变化,还是数据源变化,都能够轻松解耦,只关心业务,逻辑不用过多排查,提高了开发效率。

工程代码:

工程结构如下:

下面直接上代码:

package com.example.lixuecheng.mvpshow.view;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.Toast;

import com.example.lixuecheng.mvpshow.R;
import com.example.lixuecheng.mvpshow.adapter.MyAdapter;
import com.example.lixuecheng.mvpshow.bean.Girl;
import com.example.lixuecheng.mvpshow.presenter.GirlPresenter;

import java.util.ArrayList;
import java.util.List;

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

    ListView listView;
    GirlPresenter girlPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        List<Girl> datas = new ArrayList<>();
//        datas.add(new Girl(R.drawable.first, "小美丽"));
//        datas.add(new Girl(R.drawable.second, "小美丽"));
//        datas.add(new Girl(R.drawable.third, "小美丽"));
//        datas.add(new Girl(R.drawable.fourth, "小美丽"));
//        MyAdapter myAdapter = new MyAdapter(this, datas);
        listView = findViewById(R.id.mylistview);
//        new GirlPresenter<>(this).fetch();
        girlPresenter.fetch();
//        listView.setAdapter(myAdapter);
//        myAdapter.notifyDataSetChanged();
    }

    @Override
    public void showLoading() {
        Toast.makeText(this, "加载成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showGirls(List<Girl> girls) {
        MyAdapter myAdapter = new MyAdapter(this, girls);
        listView.setAdapter(myAdapter);

    }


    @Override
    protected GirlPresenter<IGirlView> creatPresenter() {
        return new GirlPresenter<>();
    }
}

代码中,BaseActivity将Presenter的初始化封层,通过泛型,将View层的接口传入,从而可以适配更多的VIew,IGirlVIew为View层的接口,根据需求,调整自己的接口,增加或者减少。

直接看后续关键代码;

package com.example.lixuecheng.mvpshow.view;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.example.lixuecheng.mvpshow.presenter.BasePresenter;

public abstract class BaseActivity<V, T extends BasePresenter<V>>extends Activity {
    public T girlPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        girlPresenter = creatPresenter();
        girlPresenter.attchView((V)this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        girlPresenter.dettachView();
    }

    protected abstract  T creatPresenter();
}

 BaseActivity是抽象类,通过泛型方式,拿到各个View的引用,从而和表示层建立关联。只要继承了BaseActivity,都要实现它的抽象方法,从而拿得到各自View的表示层。

package com.example.lixuecheng.mvpshow.presenter;

import com.example.lixuecheng.mvpshow.bean.Girl;
import com.example.lixuecheng.mvpshow.model.GirlModelImpl;
import com.example.lixuecheng.mvpshow.model.IGirlModel;
import com.example.lixuecheng.mvpshow.view.IGirlView;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * 表示层
 */
public class GirlPresenter<T extends IGirlView> extends BasePresenter<T>{
    //view层引用
//    IGirlView girlView;
    //model层引用
    IGirlModel iGirlModel = new GirlModelImpl();
    //model层引用
    //构造方法
    public GirlPresenter() {
//        this.girlView = view;
//        mViewRef = new WeakReference<>(view);
    }




    //执行数据
    public void fetch() {
        if(mViewRef != null) {
            mViewRef.get().showLoading();
            if(iGirlModel != null) {
                iGirlModel.loadGirl(new IGirlModel.GirlOnLoadListener() {
                    @Override
                    public void onComplete(List<Girl> girls) {
                        if(mViewRef != null) {
                            mViewRef.get().showGirls(girls);
                        }
                    }
                });
            }
        }

    }
}

 注意这里的GirlPresenter的实例化中,什么都没有做,而是将绑定View的工作都放到父类当中。

package com.example.lixuecheng.mvpshow.presenter;

import java.lang.ref.WeakReference;

public class BasePresenter<T> {
    protected WeakReference<T> mViewRef;

    //进行绑定
    public void attchView(T view) {
        mViewRef = new WeakReference<>(view);
    }
    //进行解绑
    public void dettachView() {
        mViewRef.clear();
    }
}

 通过弱引用的方式,定义view的引用,同时将绑定和解绑都通过弱引用方式完成,防止内存泄漏。这里面还有个小技巧就是数据的回调,没有采用直接数据填充回调,因为如果是网络数据,没有数据返回时候,会一直等待,具体见项目。

项目github地址:https://github.com/lixuecheng/Multi_Mvp.git

猜你喜欢

转载自blog.csdn.net/ezview_uniview/article/details/82153066
今日推荐