欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-06 11:32:49
...

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

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

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

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的生命周期加软引用的双层保险,防止出现内存泄漏

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

相关标签: android MVP