MVP模式的ListView展示数据,防止内存泄漏

来源:互联网 发布:淘宝黑搜白搜的区别 编辑:程序博客网 时间:2024/06/18 02:33

今天的内容就是用MVP模式写了一个ListView展示数据的功能,数据使用的是模拟的数据,这个里面有一个亮点就是view与presenter之间的绑定与解绑

当程序出错或者退出的时候,在我们的内存中还存在view的对象,这样容易引起内存泄漏,所以我们就要写一个解绑的方法,下面是我的项目架构

model提供数据源,这里我写的是模拟的数据,其实可以在网络上请求数据是一样的

package com.example.a111mvp.model;import java.util.List;/** * Created by 56553 on 2017/11/1. */public interface IHomeModel{    public void loadData(HomeDataCallback callback);    public interface HomeDataCallback{        public void complete(List list);    }}package com.example.a111mvp.model;import java.util.List;/** * Created by 56553 on 2017/11/1. */public interface IHomeModel{    public void loadData(HomeDataCallback callback);    public interface HomeDataCallback{        public void complete(List list);    }}

看到这个接口里面的方法有一个回调接口,当我们调用这个接口的方法的时候,就会重写这个方法下面的接口,把list传过去

model实现类

package com.example.a111mvp.model;import java.util.ArrayList;import java.util.List;/** * Created by 56553 on 2017/11/1. */public class HomeModel implements IHomeModel {    @Override    public void loadData(HomeDataCallback callback) {        List list = new ArrayList();        for (int i = 0; i <100 ; i++) {            list.add("第"+i+"条");        }        callback.complete(list);    }}
模拟的数据,实现接口,重写complete方法

view显示视图定义个方法在Mainactivity中实现

package com.example.a111mvp.view;import java.util.List;/** * Created by 56553 on 2017/11/1. */public interface IHomeView {    public void showListData(List list);}

在presenter中会与view和model交互,这里面写绑定与解绑的方法

package com.example.a111mvp.presenter;import android.util.Log;import com.example.a111mvp.model.HomeModel;import com.example.a111mvp.model.IHomeModel;import com.example.a111mvp.view.IHomeView;import java.lang.ref.WeakReference;import java.util.List;/** * Created by 56553 on 2017/11/1. */public class HomePresenter implements IPresenter<IHomeView>{    //IHomeView view;    //双层保证内存不会泄露    //软引用  在内存不足时会回收  如果activity意外终止 使用该方式    WeakReference<IHomeView> reference;    //手动释放   activity销毁时直接回收    HomeModel model;    public HomePresenter(IHomeView view) {        model = new HomeModel();        attach(view);    }    //提供一个 让model数据加载在view上的方法    public void showListData(){        model.loadData(new IHomeModel.HomeDataCallback() {            @Override            public void complete(List list) {                reference.get().showListData(list);            }        });    }    //和view层绑定    @Override    public void attach(IHomeView view) {        reference = new WeakReference(view);    }    //和view层解绑    @Override    public void detach(){        reference.clear();        Log.i("+++++++++++++++++", "detach: "+"解绑");    }}
我实现的一个接口

package com.example.a111mvp.presenter;/** * Created by 56553 on 2017/11/1. */public interface IPresenter<T> {    public void attach(T view);    public void detach();}
实现这个接口里面的方法,attach绑定,detach解绑,泛型用到IHomeview,使用到软引用的对象,内存不足的时候回回收内存,双层保险的就是还使用了一个activity的生命周期,即用onDestory,退出的时候执行销毁的方法

package com.example.a111mvp;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import com.example.a111mvp.presenter.IPresenter;/** * Created by 56553 on 2017/11/1. */public abstract class BaseActivity<T extends IPresenter> extends AppCompatActivity {    //使用泛型定义一个presenter对象  该泛型必须满足IPresenter类型,所以使用<T extends IPresenter>    T presenter;    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        createPresenter();    }    public abstract void createPresenter();    //所有的Activity销毁时    统一在baseactivity中解绑    @Override    protected void onDestroy() {        super.onDestroy();        if (presenter != null){            presenter.detach();        }    }}
定义一个带泛型的activity继承activity,这个activity实现的就是ondestory方法,接下来的mainactivity继承这个activity就会调用这个方法

package com.example.a111mvp;import android.os.Bundle;import android.widget.ArrayAdapter;import android.widget.ListView;import com.example.a111mvp.presenter.HomePresenter;import com.example.a111mvp.view.IHomeView;import java.util.List;public class MainActivity extends BaseActivity<HomePresenter> implements IHomeView{    ListView mlistview;    List mlist;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        presenter.showListData();    }    //由BaseActivity提供 在BaseActivity的oncreate方法中调用    @Override    public void createPresenter() {        presenter = new HomePresenter(this);    }    private void initView() {        mlistview = (ListView) findViewById(R.id.lv);    }    //由View接口提供的方法  使用model给的数据进行展示    @Override    public void showListData(List list) {        ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);        mlistview.setAdapter(adapter);    }}

OK,就是这样使用activity的生命周期加软引用的双层保险,防止出现内存泄漏

写的不是特别好,也有好多地方不是特别懂,写出来大家一起研究