Android TextView 内存泄漏

Posted

技术标签:

【中文标题】Android TextView 内存泄漏【英文标题】:Android TextView Memory Leakage 【发布时间】:2012-11-14 21:14:00 【问题描述】:

我正在开发一个音乐应用程序,其中使用了 Seekbar。我有一种方法可以处理搜索栏的性能,并且效果很好。但如果 seekbar 正在运行,则存在内存泄漏,并且 Log cat 显示为

GC_CONCURRENT freed 1692K, 34% free 10759K, paused 3ms+8ms

当搜索栏正在进行时,这会不断出现

我发现问题是由于TextView的动态更新,即显示当前歌曲的时长。

我该如何解决。请帮我解决这个问题

我的功能是

public void seekbarProgress()

        handler.postDelayed(new Runnable() 
            @Override
            public void run() 

                //current position of the play back 
                currPos = harmonyService.player.getCurrentPosition();
                if(isPaused)
                    //if paused then stay in the current position
                    seekBar.setProgress(currPos);
                    //exiting from method... player paused, no need to update the seekbar
                    return;
                

                //checking if player is in playing mode
                if(harmonyService.player.isPlaying())
                    //settting the seekbar to current positin
                    seekBar.setProgress(currPos);
                    //updating the cuurent playback time
                    currTime.setText(getActualDuration(""+currPos));
                    handler.removeCallbacks(this);
                    //callback the method again, wich will execute aftr 500mS
                    handler.postDelayed(this, 500);
                
                //if not playing...
                else
                    //reset the seekbar
                    seekBar.setProgress(0);
                    //reset current position value
                    currPos = 0;
                    //setting the current time as 0
                    currTime.setText(getActualDuration(""+currPos));
                    Log.e("seekbarProgress()", "EXITING");
                    //exiting from the method
                    return;
                
            
        , 500);
    

【问题讨论】:

为什么要随着搜索栏的每个进度更新曲目的长度?您可以在 MediaPlayer 准备好后更新一次。 我想在一个 Textview 中更新当前的搜索时间,还有一个 Textview 用于完整的歌曲持续时间,这个 textview 用于当前正在播放的歌曲时间。 您多久更改一次搜索栏进度?如果您的文本中不显示毫秒,您可以创建一个线程,根据搜索栏每秒更新 TextView。 我的目标是:如果一首歌曲的最大持续时间为 10000 毫秒,我的 textview maxTime 之一,在此方法之外,将显示为 00:10 ,方法是在方法 getActualDuration( timeInMillis)...需要再显示一个TextView currTime,作为歌曲的当前位置。例如:当歌曲开始播放时,它设置为 0,然后在 1 秒后它将更新为 00:01、00:02、00:02 等直到 00:10 ......就像这样 您显示的 logcat 条目并不意味着内存泄漏,它只是垃圾收集器在做它的工作。我怀疑这个""+currPos 会导致大量垃圾收集。请阅读 Java“不可变字符串”。 【参考方案1】:

GC_CONCURRENT 行并不意味着您有内存泄漏。这只是垃圾收集器清理未使用的内存。

编辑 这一行:

currTime.setText(getActualDuration(""+currPos));

不会造成内存泄漏(除非getActualDuration() 做了一些有趣的事情)。它只是每 500 毫秒创建一个新的String,但它不是内存泄漏。旧的将像您的情况一样被垃圾收集。

【讨论】:

谢谢,但是,在这种情况下,我怎样才能避免让内存不使用。当我注释掉这一行时 currTime.setText(getActualDuration(""+currPos));没有 GC_CONCURRENT,释放未使用的内存。所以我很困惑 你在说哪一行?在 java 中,你通常不需要太担心内存泄漏。如果有一个未使用的对象,它将被自动释放(除非您在某处保留对它的引用)。 (在 android 上工作)这一行 currTime.setText(getActualDuration(""+currPos));在 Log cat 中,类似的消息不断出现。 GC_CONCURRENT 释放 1692K,34% 释放 10759K,暂停 3ms+8ms 会不会导致任何性能问题, 检查我的编辑,这可能是导致日志中出现这些消息的行,但没关系 是的,我知道 GC_CONCURRENT 是由于这条线,不知道如何修复它。必须每秒显示 currTime

以上是关于Android TextView 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

Android技术分享|Android 中部分内存泄漏示例及解决方案

Android内存泄漏查找和解决

Android ValueAnimator --内存泄漏

android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

Android内存优化三:内存泄漏检测与监控

Android性能优化之利用LeakCanary检测内存泄漏及解决办法(转)