You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决移除最近应用列表后音乐播放器仍持续播放的问题?

问题解决方案:移除最近应用后停止音乐播放

当前代码的核心问题是没有处理Android系统在应用从最近列表移除时触发的onTaskRemoved回调,导致服务和音乐继续后台运行。只需添加以下修改即可实现需求:

1. 添加抽象方法让子类实现停止播放逻辑

在InvincibleService中新增一个抽象方法,让你的音乐Service子类负责实现具体的停止音乐逻辑:

protected abstract fun stopMusicPlayback()

2. 重写onTaskRemoved回调处理移除操作

在InvincibleService中重写onTaskRemoved方法,在这里执行停止播放、清理资源、销毁服务的操作:

override fun onTaskRemoved(rootIntent: Intent?) {
    // 停止音乐播放
    stopMusicPlayback()
    // 停止Invincibility的定时任务和广播监听
    invincibility?.stop()
    invincibility = null
    // 停止并销毁当前服务
    stopSelf()
    super.onTaskRemoved(rootIntent)
}

3. 子类实现停止播放逻辑

在你的音乐Service子类中实现stopMusicPlayback方法,填入具体的停止播放代码:

override fun stopMusicPlayback() {
    // 示例:停止MediaPlayer并释放资源
    mediaPlayer?.run {
        if (isPlaying) stop()
        release()
    }
    mediaPlayer = null
}

修改后的完整InvincibleService代码

abstract class InvincibleService : Service() {
    protected val handler = Handler(Looper.getMainLooper())

    protected abstract val isInvincibilityEnabled: Boolean

    protected abstract val notificationId: Int

    private var invincibility: Invincibility? = null

    private val isAllowedToStartForegroundServices: Boolean
        get() = !isAtLeastAndroid12 || isIgnoringBatteryOptimizations

    // 新增抽象方法:子类实现停止音乐逻辑
    protected abstract fun stopMusicPlayback()

    override fun onBind(intent: Intent?): Binder? {
        invincibility?.stop()
        invincibility = null
        return null
    }

    override fun onRebind(intent: Intent?) {
        invincibility?.stop()
        invincibility = null
        super.onRebind(intent)
    }

    override fun onUnbind(intent: Intent?): Boolean {
        if (isInvincibilityEnabled && isAllowedToStartForegroundServices) {
            invincibility = Invincibility()
        }
        return true
    }

    // 重写onTaskRemoved处理最近应用移除操作
    override fun onTaskRemoved(rootIntent: Intent?) {
        stopMusicPlayback()
        invincibility?.stop()
        invincibility = null
        stopSelf()
        super.onTaskRemoved(rootIntent)
    }

    override fun onDestroy() {
        invincibility?.stop()
        invincibility = null
        super.onDestroy()
    }

    protected fun makeInvincible(isInvincible: Boolean = true) {
        if (isInvincible) {
            invincibility?.start()
        } else {
            invincibility?.stop()
        }
    }

    protected abstract fun shouldBeInvincible(): Boolean

    protected abstract fun notification(): Notification?

    private inner class Invincibility : BroadcastReceiver(), Runnable {
        private var isStarted = false
        private val intervalMs = 30_000L

        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                Intent.ACTION_SCREEN_ON -> handler.post(this)
                Intent.ACTION_SCREEN_OFF -> notification()?.let { notification ->
                    handler.removeCallbacks(this)
                    startForeground(notificationId, notification)
                }
            }
        }

        @Synchronized
        fun start() {
            if (!isStarted) {
                isStarted = true
                handler.postDelayed(this, intervalMs)
                registerReceiver(this, IntentFilter().apply {
                    addAction(Intent.ACTION_SCREEN_ON)
                    addAction(Intent.ACTION_SCREEN_OFF)
                })
            }
        }

        @Synchronized
        fun stop() {
            if (isStarted) {
                handler.removeCallbacks(this)
                unregisterReceiver(this)
                isStarted = false
            }
        }

        override fun run() {
            if (shouldBeInvincible() && isAllowedToStartForegroundServices) {
                notification()?.let { notification ->
                    startForeground(notificationId, notification)
                    stopForeground(false)
                    handler.postDelayed(this, intervalMs)
                }
            }
        }
    }
}

说明

onTaskRemoved是Android系统在用户从最近应用列表中移除应用任务时触发的回调,通过重写这个方法,我们可以在用户执行该操作时立即停止音乐播放、清理服务资源并销毁服务,和Spotify、YouTube Music的行为保持一致。

内容的提问来源于stack exchange,提问作者Dhairya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:40:30