mvc
MVC 架构中,Activity/Fragment(作为 View 和 Controller)直接持有 Model 或异步任务的引用,当页面销毁时,这些长生命周期对象若未正确释放,会导致 Activity 无法被 GC 回收,形成内存泄漏。
举例:
在activity中创建一个线程执行下载任务,该线程为内部类会持有activity类的强引用,如果下载过程中,用户关闭下载页面,该activity销毁但是下载任务未结束,该activity无法回收
java
// MVC模式下的Activity(同时作为View和Controller)
public class HomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// 错误示例:AsyncTask内部类隐式持有Activity引用
new DownloadTask().execute("url");
}
// 内部类会隐式持有外部类(Activity)的强引用
private class DownloadTask extends AsyncTask<String, Void, byte[]> {
@Override
protected byte[] doInBackground(String... params) {
// 网络请求,耗时操作
return downloadData(params[0]);
}
@Override
protected void onPostExecute(byte[] result) {
// 更新UI(View层操作)
TextView textView = findViewById(R.id.result_text);
textView.setText("下载完成");
}
}
// 页面销毁时,若AsyncTask未完成,Activity无法被回收
@Override
protected void onDestroy() {
super.onDestroy();
// 未取消任务,泄漏风险
}
}
mvp
**对比mvc:
把原来的UI逻辑抽象成View接口,把原来的业务逻辑抽象成Presenter接口,model还是原来的model
基本业务逻辑示例:

示例
view: 定义展示的方法,依赖具体的activity实现
java
//顶层接口
public interface IBaseVeiw {
void showErrorMesage(String msg);
}
public interface IGoodsView extends IBaseVeiw{
void showGoodView(List<Goods> goods);
}
model:存储和获取数据的逻辑,与view没有直接联系
java
//顶层接口
public interface IGoodsModel {
void loadGoodsData(OnLoadlistener onLoadListener);
interface OnLoadlistener{
void onComplete(List<Goods> goods);
void onError(String msg);
}
}
//业务相关具体实现类
public class GoodsModel implements IGoodsModel{
@Override
public void loadGoodsData(OnLoadlistener onLoadListener) {
onLoadListener.onComplete(getData());
}
//数据应来自真实情况(网络,数据库.. )
private List<Goods> getData() {
ArrayList data = new ArrayList<>();
for(int i=0;i<10;i++){
data.add(new Goods("商品"+i,i));
}
return data;
}
}
presenter:获取view和model,将model的获取的数据用view的方法显示
在presenter中创建view的弱引用,并创建对应的绑定解绑方法在activity的生命周期调用进行绑定和解绑
java
public class GoodsPresenter<T extends IBaseVeiw> {
//IGoodsView iGoodsView;
public WeakReference<T> iGoodsView;
IGoodsModel iGoodsModel = new GoodsModel();
/*
绑定
*/
public void attachView(T view){
iGoodsView = new WeakReference<>(view);
}
/*
解除绑定
*/
public void deatchView(){
if(iGoodsView!=null){
iGoodsView.clear();
iGoodsView = null;
}
}
public void fetch(){
if(iGoodsView.get()!=null&&iGoodsModel!=null){
iGoodsModel.loadGoodsData(new IGoodsModel.OnLoadlistener() {
@Override
public void onComplete(List<Goods> goods) {
((IGoodsView)iGoodsView.get()).showGoodView(goods);
}
@Override
public void onError(String msg) {
}
});
}
}
}
在activity中使用presenter,只关心两件事,数据从哪里来,表示层选择什么
java
public class MainActivity extends AppCompatActivity implements IGoodsView {
private ActivityMainBinding binding;
private MainAdapter mainAdapter;
private GoodsPresenter goodsPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mainAdapter = new MainAdapter(R.layout.item_book);
goodsPresenter = new GoodsPresenter();
//使用弱引用
goodsPresenter.attachView(this);
goodsPresenter.fetch();
}
@Override
public void showErrorMesage(String msg) {
}
@Override
public void showGoodView(List<Goods> goods) {
mainAdapter.setNewInstance(goods);
binding.rec.setAdapter(mainAdapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
goodsPresenter.deatchView();
}
}