Android 常見的幾種記憶體洩漏
阿新 • • 發佈:2019-02-20
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();
}