Android 服务即使未绑定也会泄漏

问题描述

提前为这个冗长的问题道歉。我已经查看了类似的问题/答案,但它们似乎没有回答这个特定的问题。 我有一个背景音乐服务,用于在某些活动之间切换时启用连续的背景音乐(并在切换到其他一些活动时停止音乐),其定义如下:

public class MusicService extends Service {

    private IBinder binder = new ServiceBinder();
    MediaPlayer mediaPlayer;
    private int currentPosition;

    public MusicService() {}

    public class ServiceBinder extends Binder {
        MusicService getService() {
            return MusicService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    public void onCreate() {
        super.onCreate();
        mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.background_music);
        if (mediaPlayer != null) {
            mediaPlayer.setLooping(true);
            mediaPlayer.setVolume(1.0f,1.0f);
            currentPosition = 0;
        }
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId) {
        resumeMusic();
        return START_STICKY;
    }

    public void pauseMusic() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            currentPosition = mediaPlayer.getCurrentPosition();
        }
    }

    public void resumeMusic() {
        if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
            mediaPlayer.seekTo(currentPosition);
            mediaPlayer.start();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        binder = null;
    }
}

活动定义音乐服务相关变量,如下所示:

    private Intent backgroundMusic;
    private boolean musicServiceIsBound = false;
    protected MusicService musicService;
    private final ServiceConnection musicServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name,IBinder binder) {
            musicService = ((MusicService.ServiceBinder) binder).getService();
        }

        @Override
        public void onServicedisconnected(ComponentName name) {
            musicService = null;
        }
    };
    protected boolean doNotPauseMusicOnPause = false;

并在 onResume 和 onPuase 方法中绑定/取消绑定服务,如下所示:

    @Override
    protected void onPause() {
        super.onPause();
        if (doNotPauseMusicOnPause) {
            doNotPauseMusicOnPause = false;
        } else if (musicService != null) {
            musicService.pauseMusic();
            if (musicServiceIsBound) {
                unbindService(musicServiceConnection);
                musicServiceIsBound = false;
            }
            stopService(backgroundMusic);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        bindService(new Intent(getApplicationContext(),MusicService.class),musicServiceConnection,Context.BIND_AUTO_CREATE);
        musicServiceIsBound = true;
        backgroundMusic = new Intent();
        backgroundMusic.setClass(getApplicationContext(),MusicService.class);
        startService(backgroundMusic);
    }

但是,当我运行应用程序并切换到不应该有背景音乐的 Activity 时(即 doNotPauseMusicOnPause 为 false 并且 onPause 方法解除服务连接并停止服务),或者当我离开时该应用程序,leak canary 抱怨 MusicService 已通过 MusicService$ServiceBinder.this$0 泄漏。不确定这是如何发生的,因为我在活动的 onPuase 方法中明确取消绑定服务连接,并在服务的 onDestroy 方法中将服务的绑定字段设置为 null。任何帮助确定泄漏源的帮助将不胜感激。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)