高级MVP架构封装演变全过程

本文详细介绍了如何从无到有封装一个高级MVP架构,包括解决内存泄露、代码冗余问题,以及使用注解、工厂模式、代理模式和策略模式优化生命周期和数据存储。通过逐步讲解和实例,展示了如何构建一个可扩展的MVP架构。
摘要由CSDN通过智能技术生成

本文不会讲解什么是MVP,如果还不太了解MVP请自行查阅资料,本文重点是封装一个高级MVP架构,会详细的讲解如何一步步从无到有的封装成一个高级MVP架构过程。
众所周知普通的MVP模式存在内存泄露、代码冗余、界面意外关闭后在重建数据缓存等问题,本文最终封装的成果为一一解决这些问题,而且在使用过程中尽量做到使用简单而且可扩展,当然本文也只是提供了一种封装思路而已,如果不能满足你的需求还可以自行再进行扩展。

如果你觉得你不想看整个实现思路可以直接看最后的源码,望给点个star鼓励一下

GitHub地址:https://github.com/ljqloveyou123

文章会以5个部分来整体优化封装MVP,也是一个从无到有的过程

一、不使用MVP的代码

二、最简单的MVP实现

三、解决MVP内存泄露

四、简单抽象-解决MVP代码冗余

五、高级抽象-使用注解、工厂模式、代理模式、策略模式整体解决代码冗余、内存泄露、Presenter生命周期以及数据存储问题

不废话了,进入正题。

场景:假如界面有一个按钮,点击后请求数据,然后成功后将返回的数据设置到一个Textview中

一、不使用MVP的代码,一般我们会这么写

public class MainActivity extends AppCompatActivity {
    @FieldView(R.id.tv_text)
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewFind.bind(this);
    }

    //按钮点击事件
    public void request(View view) {
        clickRequest("101010100");
    }

    //发起请求
    public void clickRequest(final String cityId) {
        //请求接口
        Retrofit retrofit = new Retrofit.Builder()
                //代表root地址
                .baseUrl("http://www.weather.com.cn/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiService apiService = retrofit.create(ApiService.class);

        //请求
        Call<WeatherBean> weatherBeanCall = apiService.requestWeather(cityId);

        weatherBeanCall.enqueue(new Callback<WeatherBean>() {
            @Override
            public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
                //请求成功
                textView.setText(response.body().getWeatherinfo().toString());
            }

            @Override
            public void onFailure(Call<WeatherBean> call, Throwable t) {
                //请求失败
            }
        });
    }

}

上面的代码是最原始的写法,下面我们使用最简单的MVP模式来改造这个代码。

二、最简单的MVP实现

思路如下:
1、首先我们先定义一个接口,用来规定针对这个界面逻辑View需要作出的动作的接口。
2、让Activity实现这个接口中的方法,也就是V层
3、创建一个类,用来封装之前的网络请求过程,也就是M层
4、再创建一个类,用来处理M层和V层之间的通信,也就是P层

下面来实现一下:

1、首先我们先定义一个接口,用来规定针对这个界面逻辑View需要作出的动作的接口。

/**
 * @author 刘镓旗
 * @date 2017/11/16
 * @description V层接口,定义V层需要作出的动作的接口
 */
public interface RequestView1 {
    //请求时展示加载
    void requestLoading();
    //请求成功
    void resultSuccess(WeatherBean result);
    //请求失败
    void resultFailure(String result);
}

2、让Activity实现这个接口中的方法,也就是V层

 /**
 *   第二步:对应demo1
 * 2,最简单的mvp模式,
 * 1.Activity需要实现v层接口
 * 2.Persenter需要持有v层引用和m层引用
 * 3.在实现类view中创建persenter
 *
 */
public class MainActivity extends AppCompatActivity implements RequestView1 {

    @FieldView(R.id.tv_text)
    private TextView textView;
    private RequestPresenter1 presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewFind.bind(this);

        //创建Presenter
        presenter = new RequestPresenter1(this);
    }

    //点击事件
    public void request(View view) {
        presenter.clickRequest("101010100");
    }

    //请求时加载
    @Override
    public void requestLoading() {
        textView.setText("请求中,请稍后...");
    }

    //请求成功
    @Override
    public void resultSuccess(WeatherBean result) {
        //成功
        textView.setText(result.getWeatherinfo().toString());
    }

    //请求失败
    @Override
    public void resultFailure(String result) {
        //失败
        textView.setText(result);
    }
}

3、创建一个类,用来封装之前的网络请求过程,也就是M层

/**
 * @author 刘镓旗
 * @date 2017/11/16
 * @description M层 数据层
 */
public class RequestMode1 {

    private static final String BASE_URL = "http://www.weather.com.cn/";

    //http://www.weather.com.cn/data/cityinfo/101010100.html
   public void request(String detailId, Callback<WeatherBean> callback){
       //请求接口
       Retrofit retrofit  = new Retrofit.Builder()
               //代表root地址
               .baseUrl(BASE_URL)
               .addConverterFactory(ScalarsConverterFactory.create())
               .addConverterFactory(GsonConverterFactory.create())
               .build();

       ApiService apiService = retrofit.create(ApiService.class);

       //请求
       Call<WeatherBean> weatherBeanCall = apiService.requestWeather(detailId);

       weatherBeanCall.enqueue(callback);
   }
}

4、再创建一个类,用来处理M层和V层之间的通信,也就是P层

/**
 * @author 刘镓旗
 * @date 2017/11/16
 * @description P层
 * 特点:需要持有M层和V层
 */
public class RequestPresenter1 {

    private final RequestView1 mRequestView;
    private final RequestMode1 mRequestMode;

    public RequestPresenter1(RequestView1 requestView) {
        this.mRequestView = requestView;
        this.mRequestMode = new RequestMode1();
    }

    public void clickRequest(final String cityId){
        //请求时显示加载
        mRequestView.requestLoading();

        //模拟耗时,可以展示出loading
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mRequestMode.request(cityId, new Callback<WeatherBean>() {
                    @Override
                    public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
                        mRequestView.resultSuccess(response.body());
                    }

                    @O
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值