最近在写一个音乐类APP时需要从Notification发送广播给Service执行操作,但是在BroadcaseReceiver中出现onReceive()被多次调用的问题。网上搜索了很久都没找到解决方案,但也在搜索过程中收到了一些启发,于是决定把广播接收器变成单例模式,没想到效果一级棒。
/**
* 广播接收器部分,单例模式
*/
class NotificationReceiver private constructor() :
BroadcastReceiver() {
companion object {
const val PREVIOUS = "previous"
const val PAUSE = "pause"
const val PLAY = "play"
const val NEXT = "next"
val default = NotificationReceiver()
}
private var weakReference: WeakReference<MediaPlayerService>? = null
override fun onReceive(context: Context?, intent: Intent?) {
Log.d(TAG, "收到广播了,intentAction:${intent?.action}")
when (intent?.action) {
PREVIOUS -> {
weakReference?.get()?.previous()
}
PLAY -> {
weakReference?.get()?.play(false)
}
NEXT -> {
weakReference?.get()?.next()
}
PAUSE -> {
weakReference?.get()?.pause()
}
}
}
fun setWeakReference(weakReference: WeakReference<MediaPlayerService>) {
this.weakReference = weakReference
}
}
下面的MyMediaSession类用于演示注册广播
private class MyMediaSession(private val mContext: Context) {
......
private var receiver : NotificationReceiver? = null
....
// 在实例化时就把广播注册了
init {
// 注册广播
if (receiver == null) {
receiver = NotificationReceiver.default
val filter = IntentFilter()
filter.addAction(NotificationReceiver.PAUSE)
filter.addAction(NotificationReceiver.PLAY)
filter.addAction(NotificationReceiver.PREVIOUS)
filter.addAction(NotificationReceiver.NEXT)
mContext.registerReceiver(receiver, filter)
}
}
....
private fun unregister() {
mContext.unregisterReceiver(receiver)
}
....
}
这样就只能获取到一个广播接收器实例,加上receiver == null 的判断确保只注册一次