1. 程式人生 > >Android 常見的幾種記憶體洩漏

Android 常見的幾種記憶體洩漏

TimerTask物件在和Timer的schedule()方法配合使用的時候極容易造成記憶體洩露。和Handler一樣,Timer和TimerTask一直引用外部類Activity。比Handler更嚴重的是Timer一般是用來做無限迴圈,而訊息佇列終有把訊息都處理完的時候。一般Timer的程式碼如下:

void scheduleTimer() {
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            while(true);
        }
    },1000
,1000); } View ttButton = findViewById(R.id.tt_button); ttButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { scheduleTimer(); nextActivity(); } });

解決方案為在適當的時候cancel掉Timer和TimerTask。


private void cancelTimer(){ 
        if (mTimer != null
) { mTimer.cancel(); mTimer = null; } if (mTimerTask != null) { mTimerTask.cancel(); mTimerTask = null; } }

用Rxjava來實現Timer

這裡不得不提一下Rxjava。Rxjava中的Interval操作符返回一個Observable,它(在一段時間後)按固定的時間間隔發射一個無限遞增的整數序列。RxJava將這個操作符實現為interval方法。它接受(一個表示多少時間後進行迴圈的時間參賽)一個表示時間間隔的引數和一個表示時間單位的引數。結果遞增且不斷增加。

subscription = Observable.interval(1,3,TimeUnit.SECONDS).subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                Log.d("Observable","---------"+aLong);
            }
        });

上面的程式碼表示在1毫秒後每三秒鐘執行一次subscriber中的call方法。
當然為了避免記憶體洩漏也要在適當的地方進行unsubscribe。

if(subscription!=null && !subscription.isUnsubscribed()){
            subscription.unsubscribe();
        }