MVP模式的ListView展示数据,防止内存泄漏
程序员文章站
2022-05-06 11:32:49
...
今天的内容就是用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的生命周期加软引用的双层保险,防止出现内存泄漏
写的不是特别好,也有好多地方不是特别懂,写出来大家一起研究