2014-02-09 37 views
1

我的Android應用程序中有內存泄漏。這是一個簡單的音樂播放器。在屏幕的底部,我有一個TextView,用於顯示經過的時間。它在下面的線程中更新。Android runOnUiThread導致內存泄漏

每次我改變方向時,堆的大小都會增加。從查看DDMS堆更新,看起來像我的活動沒有被垃圾收集。但是,如果我按照以下的方式對6條線進行評論,則GC會保持堆的大小相當一致。你能不能讓我知道是什麼原因導致了泄漏?

private void updateTimerAndSeekBar() { 
    Thread updater = new Thread() { 
     SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1); 
     TextView timer = (TextView) findViewById(R.id.currentTime); 
     public void run() { 

      while (mediaPlayer.isPlaying()) { 

//    runOnUiThread(new Runnable() { 
//     @Override 
//     public void run() { 
//      timer.setText(msToMins(mediaPlayer.getCurrentPosition())); 
//     } 
//    }); 

       try { 
        seekbar.setProgress(mediaPlayer.getCurrentPosition()); 
        sleep(1000); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 
    updater.start(); 
} 
+0

通過DDMS生成堆轉儲並使用MAT來確定什麼是持有什麼。 – CommonsWare

+0

由於存在正在運行的線程,活動已保持活動狀態,因此您所評論的行實際上應該沒有效果。 – zapl

回答

4

每次更改方向時,Android都會創建並啓動一項新活動。內存泄漏是由於垃圾回收器無法收集不再需要的舊活動,因爲單獨的線程仍在運行,並且 - 作爲內部類 - 正在保持該活動。

要消除內存泄漏,需要在活動被破壞時停止並結束單獨的線程。

boolean stopThread; 


private void updateTimerAndSeekBar() { 

    stopThread = false; 

    Thread updater = new Thread() { 
     ... 

     while (!stopThread && mediaPlayer.isPlaying()) { 
       try { 
        seekbar.setProgress(mediaPlayer.getCurrentPosition()); 
        sleep(1000); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 
    updater.start(); 
} 



protected void onDestroy() { 
    stopThread = true; 
    super.onDestroy(); 
} 
+0

謝謝,工作完美。 – user184994