You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Media3后台视频播放:Activity销毁时无法彻底终止播放服务与通知的问题排查

Media3后台视频播放:Activity销毁时无法彻底终止播放服务与通知的问题排查

我帮你排查了下问题所在:你目前只是在Activity销毁时释放了本地的Player和MediaController引用,但没有主动终止后台的PlaybackService。Media3的MediaSessionService作为前台服务,只要MediaSession还处于活跃状态、服务没收到停止指令,就会一直驻留后台,状态栏的通知也会保留,用户自然还能通过通知恢复播放。

下面是具体的修复步骤,你可以照着修改:

1. 修正Activity的onDestroy()方法,主动停止服务

在Activity销毁时,不仅要释放播放器资源,还要明确停止后台服务,并清理所有相关引用:

@Override
protected void onDestroy() {
    // 先处理媒体播放相关逻辑,再调用父类方法
    if (mediaController != null) {
        // 停止播放
        mediaController.stop();
        // 释放MediaController
        mediaController.release();
        // 取消未完成的controllerFuture
        if (controllerFuture != null && !controllerFuture.isDone()) {
            controllerFuture.cancel(true);
        }
        mediaController = null;
        controllerFuture = null;
    }

    if (playerView != null) {
        // 解除PlayerView与播放器的绑定
        playerView.setPlayer(null);
        playerView = null;
    }

    // 主动停止后台PlaybackService
    stopService(new Intent(this, PlaybackService.class));

    super.onDestroy();
}

2. 完善PlaybackService的onDestroy(),确保资源彻底释放

虽然你已经写了服务的销毁逻辑,但可以再优化下顺序,确保播放器先停止再释放:

@Override
public void onDestroy() {
    if (mediaSession != null) {
        // 先停止播放器
        mediaSession.getPlayer().stop();
        // 释放播放器资源
        mediaSession.getPlayer().release();
        // 释放MediaSession
        mediaSession.release();
        mediaSession = null;
    }
    super.onDestroy();
}

3. 检查Manifest中的服务声明(关键!)

确认你的PlaybackService在Manifest中正确声明,必须添加对应的intent-filter和前台服务类型,否则MediaController无法正常连接服务,也会导致服务生命周期异常:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="false">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaSessionService" />
    </intent-filter>
</service>

为什么之前的代码不行?

Media3的MediaSessionService是系统级的后台服务,它的生命周期并不依附于Activity。当你通过MediaController连接服务时,系统会自动启动服务并将其设为前台(通过默认的媒体通知)。如果不主动调用stopService(),即便Activity销毁,服务也会继续运行,直到MediaSession被主动释放或者系统回收。

按照上面的步骤修改后,当Activity销毁时,会先停止播放、释放前端资源,再主动终止后台服务,服务收到停止指令后会彻底释放播放器和MediaSession,状态栏的通知也会随之消失。

内容来源于stack exchange

火山引擎 最新活动