尚學堂【官網】-西安Java培訓|c++培訓|Android培訓|安卓培訓|java視頻教程|軟件工程師|-西安雁塔尚學堂計算機學校
Android安卓教程  尚學堂首頁Java學院Android安卓教程

Android 優化Handler防止內存泄露

www.zyopwk.live 發布人:java  |  來自:本站  |  發布時間:2017-09-18 16:28:00  |  點擊次數:13062

Demo描述:

Handler可能導致的內存泄露及其優化

1 關于常見的Handler的用法但是可能導致內存泄露

2 優化方式請參考BetterHandler和BetterRunnable的實現

package cc.cc;
 
import java.lang.ref.WeakReference;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
/**
 * Demo描述:
 * Handler可能導致的內存泄露及其優化
 *
 * 1 關于常見的Handler的用法但是可能導致內存泄露
 *  請參考方法initHandler()
 * 2 優化方式請參考BetterHandler和BetterRunnable的實現
 * 
 *
 *
 */
public class MainActivity extends Activity {
  private Handler mHandler;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }
   
   
  /**
   * 常見的Handler的用法但是可能導致內存泄露
   *
   * 比如在旋轉屏幕時該Activity重新繪制.
   * 但是因為mHandler發送了一個延遲消息,所以消息隊列持有mHandler對象
   * 又由于new Runnable(){}持有外部類MainActivity的引用
   * 所以Activity所占內存并不能向期望的那樣被回收,這樣就可能會造成內存泄漏.
   *
   * 這個例子中Handler的延遲時間比較久有20S,有點極端了,一般不會這么干;
   * 這里只是為了更好地說明這個問題就這么寫代碼了。
   *
   */
  private void initHandler() {
    mHandler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
        super.handleMessage(msg);
      }
    };
 
    // ......doing something
    // ......doing something
    // ......doing something
 
    // 發送延遲消息
    mHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
 
      }
    }, 1000 * 20);
  }
   
   
   
  /**
   * 以下為優化方式
   * 1 在此處把BetterHandler和BetterRunnable都設計為靜態類,
   * 這樣它們就不會持有外部類的引用了.
   * 2 在BetterHandler中利用WeakReference持有Activity.
   * 常聽說:"如果一個對象具有弱引用,那么當GC線程掃描的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存"
   * 其實準備地說應該是"如果一個對象只具有弱引用.........",即僅有弱引用而不存在對其的強引用才會將其回收.
   * 那么此處對Activity采用了弱引用,會不會導致該Activity被回收呢?
   * 答案是否定的。因為此處的Activity還在顯示界面,當然存在其他對象對它的強引用。所以不會對其回收。
   * 
   * 經過這樣的優化,當旋轉屏幕時需要銷毀原Activity時;消息隊列持有Handler對象.但此時Handler對象不再持有Activity的引用.
   * 所以系統會回收該Activity所占內存.所以在handleMessage()中處理消息時需要判斷Activity是否為空.
   * 比如此處20秒后才處理消息 這個時候Activity為空.
   */
  private static class BetterHandler extends Handler{
    private final WeakReference<Activity> activityWeakReference;
    public BetterHandler(Activity activity){
      activityWeakReference=new WeakReference<Activity>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      if (activityWeakReference.get()!=null) {
        //.....handle message
      } else {
        System.out.println("Activity==null");
      }
    }
  }
   
  //同樣采用靜態內部類
  private static class BetterRunnable implements Runnable{
    @Override
    public void run() {
      // ......doing something
    }
     
  }
   
  //發送延遲消息
  private void sendMessage(){
    BetterHandler betterHandler=new BetterHandler(MainActivity.this);
    betterHandler.postDelayed(new BetterRunnable(), 1000 * 20);
  }
   
 
}

 

 

當前文:Android 優化Handler防止內存泄露
上一頁:安卓手機操作系統用什么語言編寫的?
下一頁:Android 軟鍵盤狀態并隱藏輸入法的實例
在線報名(*為必填項)
云南快乐十分开奖走势图