程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Android中Handler惹起的內存洩漏成績處理方法

Android中Handler惹起的內存洩漏成績處理方法

編輯:關於JAVA

Android中Handler惹起的內存洩漏成績處理方法。本站提示廣大學習愛好者:(Android中Handler惹起的內存洩漏成績處理方法)文章只能為提供參考,不一定能成為您想要的結果。以下是Android中Handler惹起的內存洩漏成績處理方法正文


成績描寫

生怕年夜家都邑碰到如許的成績,一個點擊事宜屢次觸發,招致,異樣的內容提交了屢次,或許說彈出多個頁面...

onClick事宜是Android開辟中最多見的事宜。好比,一個submitButton,功效是點擊以後會提交一個定單,則普通代碼以下,個中submitOrder()函數會跳轉到下一頁停止處置 :

<code class="hljs" java="">  //代碼0
  submitButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    submitOrder();
   }
  }); </code>

正常情形下這段代碼是沒甚麼成績的,然則Android裝備的機型機能等千差萬別,假如碰著比擬卡的手機,則有能夠湧現submitOrder()函數跳轉頁面湧現延遲的景象。碰著這類景象,則用戶就很有能夠再次點擊一次,從而形成函數被挪用兩次,湧現反復定單的BUG。

普通地,碰著這景象,起首就會想到的就是在點擊以後把submitButton設置為弗成點擊:

<code class="hljs" cs="">  //代碼1
  submitButton.setClickable(false);
  //或許 
  submitButton.setEnabled(false); </code>

此辦法也確切有用,不外假如submitOrder()辦法沒有勝利,須要再次提交定單時又須要再反復把submitButton設置為可點擊狀況。假如相似的button比擬多時,就顯得比擬費事、凌亂。

計劃

自界說一個NoDoubleClickListener,繼續自OnClickListener:

<code class="hljs" java="">  //代碼2
  public abstract class NoDoubleClickListener implements OnClickListener {
   public static final int MIN_CLICK_DELAY_TIME = 1000;
   private long lastClickTime = 0;
   @Override
   public void onClick(View v) {
    long currentTime = Calendar.getInstance().getTimeInMillis();
    if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
     lastClickTime = currentTime;
     onNoDoubleClick(v);
    } 
   } 
  }</code>

應用辦法—— 給submitButton設置點擊事宜時用NoDoubleClickListener取代OnClickListener,而且完成辦法onNoDoubleClick取代onClick便可,像如許:

<code class="hljs" java="">  //代碼3
  submitButton.setOnClickListener(new NoDoubleClickListener() {
   @Override
   public void onNoDoubleClick(View v) {
    submitOrder();
   }
  }); </code>

道理:

很簡略,見代碼……

就是用onNoDoubleClick取代onClick處置詳細的操作,在onClick辦法中加一個斷定:在吸收到點擊事宜以後,先斷定一下時光,假如間隔前次處置操作缺乏MIN_CLICK_DELAY_TIME,就疏忽——即能避免誤操作的持續點擊招致反復事宜。

MIN_CLICK_DELAY_TIME可調。

優勢

利益是不消轉變原有代碼的邏輯,就只須要兩個調換:NoDoubleClickListener取代OnClickListener,onNoDoubleClick取代onClick。 代碼的構造等都不須要做轉變(**比較下面的代碼0跟代碼**3),不須要關懷處置更改button的狀況這些額定斷定邏輯,只須要存眷營業邏輯便可,簡練優雅~

��面的代碼,當我們履行了Activity的finish辦法,被延遲的新聞會在被處置之前存在於主線程新聞隊列中10分鐘,而這個新聞中又包括了Handler的援用,而Handler是一個匿名外部類的實例,其持有裡面的SampleActivity的援用,所以這招致了SampleActivity沒法收受接管,停止招致SampleActivity持有的許多資本都沒法收受接管,這就是我們常說的內存洩漏。

留意下面的new Runnable這裡也是匿名外部類完成的,異樣也會持有SampleActivity的援用,也會阻攔SampleActivity被收受接管。

要處理這類成績,思緒就是不實用非靜態外部類,繼續Handler時,要末是放在零丁的類文件中,要末就是應用靜態外部類。由於靜態的外部類不會持有內部類的援用,所以不會招致內部類實例的內存洩漏。當你須要在靜態外部類中挪用內部的Activity時,我們可使用弱援用來處置。別的關於異樣也須要將Runnable設置為靜態的成員屬性。留意:一個靜態的匿名外部類實例不會持有內部類的援用。 修正後不會招致內存洩漏的代碼以下:

public class SampleActivity extends Activity {

  /**
   * Instances of static inner classes do not hold an implicit
   * reference to their outer class.
   */
  private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }

  private final MyHandler mHandler = new MyHandler(this);

  /**
   * Instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() { /* ... */ }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Post a message and delay its execution for 10 minutes.
    mHandler.postDelayed(sRunnable, 1000 * 60 * 10);

    // Go back to the previous Activity.
    finish();
  }
}

其其實Android中許多的內存洩漏都是因為在Activity中應用了非靜態外部類招致的,就像本文提到的一樣,所以當我們應用時要非靜態外部類時要非分特別留意,假如其實例的持有對象的性命周期年夜於其內部類對象,那末就有能夠招致內存洩漏。小我偏向於應用文章的靜態類和弱援用的辦法處理這類成績。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved