国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android開發:淺談MVP模式應用與內存泄漏問題解決

2019-12-12 04:31:06
字體:
來源:轉載
供稿:網友

最近博主開始在項目中實踐MVP模式,卻意外發現內存泄漏比較嚴重,但卻很少人談到這個問題,促使了本文的發布,本文假設讀者已了解MVP架構。

MVP簡介

M-Modle,數據,邏輯操作層,數據獲取,數據持久化保存。比如網絡操作,數據庫操作

V-View,界面展示層,Android中的具體體現為Activity,Fragment 

P-Presenter,中介者,連接Modle,View層,同時持有modle引用和view接口引用

示例代碼
Modle層操作

public class TestModle implements IModle{  private CallbackListener callback;  public TestModle(CallbackListener callback) {    this.callback = callback;  }  public interface CallbackListener {    void onGetData(String data);  }  public void getData() {    new Thread() {      public void run() {        callback.onGetData("返回的數據");      }    }.start();  }}

View層

// 抽象的view層public interface TestViewInterf extends IView {  void onGetData(String data);}// 具體的View層public class MainActivity extends Activity implements TestViewInterf{  private TestPresenter mTestPresenter;  @Override  public void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    // view層將獲取數據的任務委派給中介者presenter,并傳入自身實例對象,實現TestViewInterf接口    mTestPresenter = new TestPresenter(this);    mTestPresenter.getData();  }  @Override  public void onGetData(String data) {    // View層只做數據展示    showToast(data);  }  private void showToast(String toast) {    Toast.makeText(this, toast, Toast.LENGTH_LONG).show();  }}

Presenter中介者

public class TestPresenter implements IPresenter{  IModle modle;  IView view;  public TestPresenter(IView view) {    this.view = view;  }  public void getData() {    // 獲取數據的操作實際在Modle層執行    modle = new TestModle(new CallbackListener() {      public void onGetData(String data) {        if (view != null) {          view.onGetData(data);        }      }    });    modle.getData();  }}

根據OOP思想,Java應面向接口編程,這樣才能給符合OCP原則。上述示例代碼省略了更加抽象的接口IModle,IView,IPresenter,并且實際MVP實踐中通常會引入泛型使其更具擴展性。

Google已提供了相關示例代碼,并在MVP中增加了一個約束者:Contract,它的作用是定義各個模塊的MVP接口。
google MVP sample code:https://github.com/googlesamples/android-architecture

內存泄露問題

由上可見,Presenter中持有View接口對象,這個接口對象實際為MainActivity.this,Modle中也同時擁有Presenter對象實例,當MainActivity要銷毀時,Presenter中有Modle在獲取數據,那么問題來了,這個Activity還能正常銷毀嗎?

答案是不能! 

當Modle在獲取數據時,不做處理,它就一直持有Presenter對象,而Presenter對象又持有Activity對象,這條GC鏈不剪斷,Activity就無法被完整回收。 

換句話說:Presenter不銷毀,Activity就無法正常被回收。

解決MVP的內存泄露

Presenter在Activity的onDestroy方法回調時執行資源釋放操作,或者在Presenter引用View對象時使用更加容易回收的軟引用,弱應用。 

比如示例代碼:
Activity

@Override  public void onDestroy() {    super.onDestroy();    mPresenter.destroy();  }

Presenter

public void destroy() {  view = null;  if(modle != null) {    modle.cancleTasks();  }}

Modle

public void cancleTasks() {  // TODO 終止線程池ThreadPool.shutDown(),AsyncTask.cancle(),或者調用框架的取消任務api}

個人總結

因為面向MVP接口編程,可適應需求變更,所以MVP適用于比較大的項目;因為其簡化了Activity和Fragmnt的職責,可大大減少View層的代碼量,比起MVC中Activity,Fragment動不動上千行的代碼量,簡直優雅!

做完以上操作,由于MVP引起的內存泄露就差不多解決了,以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宜章县| 玛多县| 平塘县| 平昌县| 会昌县| 仁化县| 武清区| 吉水县| 东乌珠穆沁旗| 乌恰县| 建昌县| 平度市| 桂阳县| 团风县| 邛崃市| 巴东县| 武宁县| 库伦旗| 文山县| 广州市| 二连浩特市| 延安市| 海门市| 加查县| 陈巴尔虎旗| 门头沟区| 临武县| 永州市| 浪卡子县| 南木林县| 甘谷县| 彭水| 柳河县| 黄山市| 青浦区| 高清| 佛冈县| 柳林县| 鹤山市| 玛多县| 方山县|