应用被杀重启后Media Controller无法连接问题排查
问题分析与解决方案
核心问题根源
当应用在音频播放状态下被杀死时,后台的MediaSessionService仍在持续运行;重启应用后,Dagger注入的MusicServiceConnection单例虽会重新实例化,但内部的媒体浏览器连接逻辑未正确触发,或连接状态未及时同步,导致MediaController处于未连接状态,进而引发功能失效。而暂停时杀进程会连带终止后台MediaSessionService,重启时服务与连接会同步初始化,因此无问题。
具体修复方案
1. 强制MusicServiceConnection实例化时主动触发连接
确保MusicServiceConnection的init块中明确执行连接操作,且避免重复连接:
class MusicServiceConnection @Inject constructor( private val context: Context ) { private val mediaBrowser: MediaBrowser init { // 每次实例化都新建MediaBrowser,避免复用旧实例 mediaBrowser = MediaBrowser.Builder(context, ComponentName(context, YourMediaSessionService::class.java)) .build() Log.d("MusicServiceConnection", "实例化,开始连接媒体浏览器") // 主动触发连接 connectIfNeeded() } private fun connectIfNeeded() { if (!mediaBrowser.isConnected) { mediaBrowser.connect() } } // 其他逻辑... }
2. 监听连接状态,自动重连
给MediaBrowser和MediaController添加断开/连接失败监听,主动触发重连:
private val mediaBrowserCallback = object : MediaBrowser.Callback() { override fun onConnectionFailed() { super.onConnectionFailed() // 连接失败后延迟重试 Handler(Looper.getMainLooper()).postDelayed({ connectIfNeeded() }, 1000) } override fun onConnected() { super.onConnected() // 获取Controller并添加断开监听 val controller = MediaController.Builder(context, mediaBrowser.sessionToken).build() controller.addListener(object : MediaController.Listener() { override fun onDisconnected() { super.onDisconnected() connectIfNeeded() } }) // 同步Controller状态到UI updateControllerState(controller) } } // 在init块中给mediaBrowser设置callback init { // ... 之前的代码 mediaBrowser.setCallback(mediaBrowserCallback) }
3. 修复ViewModel中的状态监听逻辑
在ViewModel中,确保观察MusicServiceConnection的连接状态时,若初始状态为未连接,主动触发连接检查:
class YourMusicViewModel @Inject constructor( private val musicServiceConnection: MusicServiceConnection ) : ViewModel() { init { // 检查连接状态,未连接则触发连接 if (!musicServiceConnection.isConnected) { musicServiceConnection.connectIfNeeded() } // 观察连接状态变化 musicServiceConnection.isConnected.observeForever { isConnected -> if (isConnected) { // 同步播放状态等数据 syncPlaybackState() } } } // 其他逻辑... }
4. 避免复用MediaBrowser实例
不要将MediaBrowser声明为单例,确保每次MusicServiceConnection实例化时都创建新的MediaBrowser对象,避免进程重启后复用旧的失效实例。
验证方案
- 启动应用并开始播放音频
- 从最近任务划除应用杀死进程
- 重新启动应用,检查
MusicServiceConnection的init日志是否触发,媒体浏览器是否成功连接 - 验证播放、暂停等功能是否正常
内容的提问来源于stack exchange,提问作者pollux552
相关产品推荐
相关产品推荐

