Android runOnUiThread导致内存泄漏

时间:2014-02-09 22:27:19

标签: android memory-leaks

我的Android应用程序中有内存泄漏。这是一个简单的音乐播放器。在屏幕的底部,我有一个TextView,用于显示已用时间。它在下面的主题中更新。

每次更改方向时,堆大小都会增加。从查看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();
}

1 个答案:

答案 0 :(得分: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();
}