“请勿将Android上下文类放在静态字段中;这是“内存泄漏". -静态视图的棉绒警告 [英] "Do not place Android context classes in static fields; this is a memory leak" - Lint Warning for static View

查看:153
本文介绍了“请勿将Android上下文类放在静态字段中;这是“内存泄漏". -静态视图的棉绒警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些问题的标题相似,但都与您在构造函数中获得的Context有关.

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

There are RecyclerView with items and some other views where play\pause button is present.

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

This class allows this views to play only one file at a time. If view_1 is playing and you press play at view_2 - file_2 will be played.

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

There is an ImageButton mPlayPauseButton in this class. It is needed to set ImageButton at view_1 to paused_state. And set ImageButton at view_2 to playing_state.

棉绒警告

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

Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run) A static field will leak contexts.

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

警告:请勿将Android上下文类放置在静态字段中;这是内存泄漏(并且还会中断即时运行)不能解决我的问题.

推荐答案

请勿在static字段中放置小部件.

Do not put widgets in static fields.

选项包括:

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

  1. Delete this class. Move all of this logic into the activity (or fragment), where you have direct access to the widgets.

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

Use an event bus (LocalBroadcastManager, greenrobot's EventBus, etc.). Have your code here post messages on the bus when the state changes. Have your UI (activity or fragment) subscribe for messages on the bus and update the widgets.

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

Have your activity/fragment hold an instance of CommentsAudioPlayer, and make the fields in CommentsAudioPlayer non-static.

这三个选项中的第一个选项将更简单,更干净,内存占用更少并且执行速度更快.

Of the three, the first option would be simpler, cleaner, less memory-intensive, and faster to execute.

这篇关于“请勿将Android上下文类放在静态字段中;这是“内存泄漏". -静态视图的棉绒警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆