搭建MVC框架
public class MainActivity extends AppCompatActivity {
private ListView listView;
private ArrayList list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
listView = findViewById(R.id.listView);
listView.setAdapter(new GoodsAdapter(this,list));
}
private void initData() {
list.add("apple");
list.add("banana");
list.add("orange");
list.add("pear");
list.add("strawberry");
list.add("watermelon");
}
}
public class GoodsAdapter extends BaseAdapter {
private Context context = null;
private List dataList;
public GoodsAdapter(Context context, List dataList) {
this.context = context;
this.dataList = dataList;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_listview, null);
textView = convertView.findViewById(R.id.textView);
convertView.setTag(textView);
} else {
textView = (TextView) convertView.getTag();
}
textView.setText(dataList.get(position));
return convertView;
}
}
MVC框架有一个致命的问题是Activity的内存泄漏,使用MVP是有办法根除内存泄漏的。
搭建MVP基本框架
MVP的核心思想:MVC中原来的UI逻辑抽象成View接口,原来的业务逻辑抽象成Presenter接口,Model还是原来的Model。
public interface IBaseView {
void showErrorMessage(String msg);
}
public interface IGoodsModel {
void loadGoodData(OnLoadListener onLoadListener);
interface OnLoadListener {
void onComplete(List goods);
void onError(String msg);
}
}
public class GoodsModel implements IGoodsModel {
@Override
public void loadGoodData(OnLoadListener onLoadListener) {
onLoadListener.onComplete(getData());
}
public List getData() {
ArrayList list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");
list.add("pear");
list.add("strawberry");
list.add("watermelon");
return list;
}
}
public class GoodsPresenter {
//持有View层的引用
IGoodsView iGoodsView;
//持有Model层的引用
IGoodsModel iGoodsModel = new GoodsModel();
public GoodsPresenter(T view){
iGoodsView = view;
}
public void fetch(){
if(iGoodsView!=null && iGoodsModel!=null){
iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
@Override
public void onComplete(List goods) {
iGoodsView.showGoodsView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
}
public class MainActivity extends AppCompatActivity implements IGoodsView {
private ListView listView;
GoodsPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
presenter = new GoodsPresenter(this);
presenter.fetch();
}
@Override
public void showGoodsView(List data) {
listView.setAdapter(new GoodsAdapter(this, data));
}
@Override
public void showErrorMessage(String msg) {
}
}
最基本的MVP框架搭建完成,这样写很容易发生内存泄漏。为什么呢?
现在Presenter持有View的引用,如果GoodsPresenter在做网络操作的时候时间比较长,用户随时都会退到前台,但是GoodsPresenter一直持有Activity的引用,就会造成内存泄漏,和MVC的问题是一样的。
该怎么处理呢?可以使用弱引用
性能优化,根除Activity内存泄漏
public class GoodsPresenter {
//持有View层的引用
public WeakReference iGoodsView;
//持有Model层的引用
IGoodsModel iGoodsModel = new GoodsModel();
public GoodsPresenter(T view) {
iGoodsView = new WeakReference<>(view);
}
public void fetch() {
if (iGoodsView != null && iGoodsModel != null) {
iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
@Override
public void onComplete(List goods) {
iGoodsView.get().showGoodsView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
}
虽然弱引用能解决内存泄漏问题,但是延迟性比较高。
弱引用是在下一次GC的时候回收弱引用,为了使回收的动作更快一点,可以采用绑定/解绑的方式。
attachView():在Activity/Fragment执行生命周期方法onCreate()的时候
detachView():Activity/Fragment执行执行生命周期方法onDestroy()的时候
public class GoodsPresenter {
//持有View层的引用
public WeakReference iGoodsView;
//持有Model层的引用
IGoodsModel iGoodsModel = new GoodsModel();
public void attachView(T view) {
iGoodsView = new WeakReference<>(view);
}
public void detachView() {
if (iGoodsView != null) {
iGoodsView.clear();
iGoodsView = null;
}
}
public void fetch() {
if (iGoodsView != null && iGoodsModel != null) {
iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
@Override
public void onComplete(List goods) {
iGoodsView.get().showGoodsView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
}
public class MainActivity extends AppCompatActivity implements IGoodsView {
private ListView listView;
GoodsPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
presenter = new GoodsPresenter();
presenter.attachView(this);
presenter.fetch();
}
@Override
public void showGoodsView(List data) {
listView.setAdapter(new GoodsAdapter(this, data));
}
@Override
public void showErrorMessage(String msg) {
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView();
}
}
进一步优化,抽取BasePresenter
public class BasePresenter {
//持有View层的引用
public WeakReference iGoodsView;
public void attachView(T view) {
iGoodsView = new WeakReference<>(view);
}
public void detachView() {
if (iGoodsView != null) {
iGoodsView.clear();
iGoodsView = null;
}
}
}
简化GoodsPresenter ,非常的简洁
public class GoodsPresenter extends BasePresenter {
//持有Model层的引用
IGoodsModel iGoodsModel = new GoodsModel();
public void fetch() {
if (iGoodsView != null && iGoodsModel != null) {
iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
@Override
public void onComplete(List goods) {
((IGoodsView)iGoodsView.get()).showGoodsView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
}
抽取BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
protected T presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
presenter = createPresenter();
presenter.attachView((V) this);
registerSDK();
init();
}
protected abstract T createPresenter();
protected void registerSDK() { }
protected void unRegisterSDK() { }
protected void init() { }
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView();
unRegisterSDK();
}
}
简化MainActivity
public class MainActivity extends BaseActivity implements IGoodsView {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
presenter.fetch();
}
@Override
protected GoodsPresenter createPresenter() {
return new GoodsPresenter();
}
@Override
public void showGoodsView(List data) {
listView.setAdapter(new GoodsAdapter(this, data));
}
@Override
public void showErrorMessage(String msg) {
}
}
基本的MVP架构完成
Jetpack新技术和LifeCycle的融入
LifeCycle是管理生命周期,使用的是一种观察者模式。
Observable被观察者
Activity或者Fragment可以作为被观察者Observable,只要去实现LifecycleOwner接口,就能被别人观察到生命周期。
Observer观察者
任何一个类实现LifecycleObserver接口,就能作为一个观察者,就可以监听到Activity的生命周期。只要Activity的生命周期发生变化,那么UserClass就会收到反馈。
举例说明一下:
public class BasePresenter implements LifecycleObserver {
//持有View层的引用
public WeakReference iGoodsView;
public void attachView(T view) {
iGoodsView = new WeakReference<>(view);
}
public void detachView() {
if (iGoodsView != null) {
iGoodsView.clear();
iGoodsView = null;
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void abc(LifecycleOwner owner) {
}
}
只要Activity执行生命周期方法onCreate(),那么abc()方法就会执行.所以只要BasePresenter去实现LifecycleObserver ,那么就可以监听到Activity的生命周期的变化。
接下可以看下可以监听的生命周期方法有下面这些
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestory(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onAny(LifecycleOwner owner) {
}
public class BasePresenter implements LifecycleObserver {
//持有View层的引用
public WeakReference iGoodsView;
public void attachView(T view) {
iGoodsView = new WeakReference<>(view);
}
public void detachView() {
if (iGoodsView != null) {
iGoodsView.clear();
iGoodsView = null;
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestory(LifecycleOwner owner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void onAny(LifecycleOwner owner) {
}
}
在GoodsPresenter去复写onCreate()方法和onDestory()方法
public class GoodsPresenter extends BasePresenter {
//持有Model层的引用
IGoodsModel iGoodsModel = new GoodsModel();
public void fetch() {
if (iGoodsView != null && iGoodsModel != null) {
iGoodsModel.loadGoodData(new IGoodsModel.OnLoadListener() {
@Override
public void onComplete(List goods) {
((IGoodsView)iGoodsView.get()).showGoodsView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
@Override
void onCreate(LifecycleOwner owner) {
super.onCreate(owner);
Log.i("TAG","onCreate*****");
}
@Override
void onDestory(LifecycleOwner owner) {
super.onDestory(owner);
Log.i("TAG","onDestory*****");
}
}
因为在AppCompatActivity已经实现LifecycleOwner接口,所以MainActivity不需要再去实现改接口。
调用 getLifecycle().addObserver(presenter)实现绑定
public class MainActivity extends BaseActivity implements IGoodsView {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
presenter.fetch();
}
@Override
protected GoodsPresenter createPresenter() {
return new GoodsPresenter();
}
@Override
public void showGoodsView(List data) {
listView.setAdapter(new GoodsAdapter(this, data));
}
@Override
public void showErrorMessage(String msg) {
}
@Override
protected void init() {
super.init();
getLifecycle().addObserver(presenter);
}
}
总结下,使用Lifecycle去监听Activity或者Fragment生命周期的方法。
1、类A 实现接口LifecycleObserver
2、类B getLifecycle().addObserver(new 类A());
这样实现绑定是不会内存泄漏的。