"不要将Android上下文类放在静态字段中;这是一个内存泄漏" - 静态视图的{l}警告

时间:2017-05-24 22:08:52

标签: java android memory-leaks

有类似标题的问题,但它们都与构造函数中的Context有关。

有RecyclerView包含项目和其他一些视图,其中存在播放\暂停按钮。

此类允许此视图一次只播放一个文件。如果正在播放view_1并且您在view_2按下播放 - 将播放file_2。

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

Lint警告

不要将Android上下文类放在静态字段中;这是内存泄漏(也打破了Instant Run) 静态字段会泄漏上下文。

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;
    }
}

2 个答案:

答案 0 :(得分:1)

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

选项包括:

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

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

  3. 让您的活动/片段包含CommentsAudioPlayer的实例,并在CommentsAudioPlayer非 - static中填写字段。

  4. 在这三个中,第一个选项更简单,更清晰,内存更少,执行速度更快。

答案 1 :(得分:0)

您应该将view(mPlayPauseButton)与该功能分离以避免泄漏。为此,您可以实现一个侦听器模式。该代码中更简单的方法是将“侦听器”对象作为参数传递,而不是直接传递给视图引用...