当前位置: 首页 > 面试题库 >

“请勿将Android上下文类放在静态字段中;这是内存泄漏”-静态视图的Lint警告

康秋月
2023-03-14
问题内容

有些问题的标题相似,但所有问题都与您在构造函数中获得的上下文有关。

有带有项目的RecyclerView和其他带有播放\暂停按钮的视图。

此类允许该视图一次仅播放一个文件。如果正在播放view_1,然后在view_2上按播放,则将播放file_2。

此类中有一个 ImageButton mPlayPauseButton。需要将view_1的 ImageButton
设置为paused_state。并将view_2处的 ImageButton 设置为playing_state。

棉绒警告

不要将Android上下文类放在静态字段中; 这是内存泄漏(并且还会中断即时运行)。静态字段将泄漏上下文。

public class CommentsAudioPlayer {

    private static MediaPlayer mPlayer;
    private static ImageButton mPlayPauseButton;

    private static void init(ImageButton imageButton){
        mPlayer = new MediaPlayer();
        mPlayPauseButton = imageButton;
    }

    public static void startPlaying(String dataSource, ImageButton imageButton) {
        init(imageButton);

        try {
            mPlayer.setDataSource(dataSource);
            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopPlaying();
                }
            });
            mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mPlayer.start();
                }
            });
            mPlayer.prepareAsync();
            if (mPlayPauseButton != null) mPlayPauseButton.setSelected(true);
        } catch (Exception e) {
            Log.e("Player", "Error trying to start playing:\n" + e.toString());
        }
    }

    public static void stopPlaying() {
        if (mPlayPauseButton != null)
            mPlayPauseButton.setSelected(false);
        mPlayPauseButton = null;

        if (mPlayer!=null)
            mPlayer.release();
        mPlayer = null;
    }
}

问题答案:

不要将小部件放在static字段中。

选项包括:

  1. 删除此类。将所有这些逻辑移到活动(或片段)中,您可以在其中直接访问小部件。

  2. 使用事件总线(LocalBroadcastManager,greenrobot的EventBus等)。状态更改时,让您的代码在总线上发布消息。让您的UI(活动或片段)订阅总线上的消息并更新窗口小部件。

  3. 让您的活动/片段持有的实例CommentsAudioPlayer,并将字段设置CommentsAudioPlayer为非static

在这三个选项中,第一个选项将更简单,更简洁,内存占用更少,执行速度更快。



 类似资料:
  • 我正在调试一个我在Tomcat应用程序中多年来遇到的问题——由于Webapp类加载器无法通过气相色谱重新启动应用程序时导致的内存泄漏。我用JProfiler对堆进行了快照,似乎至少我的一些静态变量没有被释放。 某些类有一个静态 final 成员,该成员在首次加载类时初始化,并且因为它是 final,所以我无法在应用程序关闭时将其设置为 null。 静态最终变量是Tomcat中的反模式,还是我错过了

  • 我有一个用Java编写的基于Android Studio的应用程序。我工作正常,不会导致Android Studio抱怨任何事情: 然后我去要求Android Studio将其从Java转换为Kotlin。转换后,MainActivity如下所示: 否则,与 Java 版本一样,但类变量主活动上下文已从主活动的顶部移动到伴随对象。现在,该应用程序再次运行良好,但Android Studio抱怨主要

  • 根据JLS §8.1.3,为什么Java不允许在内部类中建立静态上下文?

  • 我知道静态字段会导致内存泄漏,因为它们不会被 GC 处理。 但是,当有一个 Web 应用程序部署在容器(例如 Tomcat)中时,每个应用程序都有自己的 ClassLoader,并且可以取消部署。 我的问题是,垃圾收集器是否声明将要卸载的类的静态成员引用的对象? 最简单的情况是单例(由引用自身的静态变量实现),如果应用程序被取消部署,它会被GCed吗?

  • 问题内容: 只是为了澄清我正在考虑的这个权利,在Java中,静态字段是整个类使用的变量/字段,还是可以用于引用该类的所有对象?非静态字段是由对象定义的变量吗?并且与对象1引用相同类的第二个对象可以具有与对象1的静态字段不同的值吗? 问题答案: 与实例变量不同,在创建该类的实例之前,可以访问该类中的静态字段或静态类变量。在运行时创建该类的实例时,将创建该类中的实例变量(非静态变量)。因此,直到创建该