android - 服务的`onStartCommand`被反复调用,不确定
问题描述
我正在尝试在前台服务(不是MediaBrowserServiceCompat
)中运行 exoplayer。
这是我的服务-
@AndroidEntryPoint
class PodcastPlayerService: Service() {
@Inject
lateinit var dataSourceFactory: DefaultDataSourceFactory
@Inject
lateinit var exoPlayer: SimpleExoPlayer
lateinit var podcastNotificationManager: PodcastNotificationManager
lateinit var podcast: Podcast
override fun onDestroy() {
super.onDestroy()
exoPlayer.release()
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
exoPlayer.stop()
exoPlayer.release()
}
override fun onBind(p0: Intent?): IBinder? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i("Pit stop", "2")
val b = intent!!.getBundleExtra("test")
if (b != null) {
Log.i("Pit stop", "3")
podcast = b.getParcelable<Podcast>(ArgumentKeyAndValues.KEY_PODCAST)!!
}
val mediaSource = buildMediaSource(Uri.parse("https://something.etc/file.mp3"))
if (mediaSource != null) {
exoPlayer.prepare(mediaSource)
exoPlayer.playWhenReady = true
podcastNotificationManager =
PodcastNotificationManager(
this,
PodcastPlayerNotificationListener(this)
)
podcastNotificationManager.showNotification(exoPlayer)
}
return START_STICKY
}
private fun buildMediaSource(uri: Uri): MediaSource? {
return ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri)
}
}
通知监听器 -
class PodcastPlayerNotificationListener(private val podcastPlayerService: PodcastPlayerService):
PlayerNotificationManager.NotificationListener {
override fun onNotificationPosted(
notificationId: Int,
notification: Notification,
ongoing: Boolean) {
super.onNotificationPosted(notificationId, notification, ongoing)
podcastPlayerService.apply {
if(ongoing) {
ContextCompat.startForegroundService(this,
Intent(applicationContext, this::class.java))
startForeground(OtherConstants.PODCAST_NOTIFICATION_ID, notification)
}
}
}
override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
super.onNotificationCancelled(notificationId, dismissedByUser)
podcastPlayerService.apply {
stopForeground(true)
stopSelf()
}
}
}
播客通知管理器 -
class PodcastNotificationManager(private val context: Context,
notificationListener: PlayerNotificationManager.NotificationListener) {
private val notificationManager: PlayerNotificationManager
init {
notificationManager = PlayerNotificationManager.createWithNotificationChannel(
context,
OtherConstants.NOTIFICATION_CHANNEL_ID,
R.string.notification_channel_name,
R.string.notification_channel_description,
OtherConstants.PODCAST_NOTIFICATION_ID,
DescriptionAdapter(),
notificationListener
).apply {
setSmallIcon(R.drawable.exo_icon_play)
}
}
fun showNotification(player: Player) {
notificationManager.setPlayer(player)
}
private inner class DescriptionAdapter : PlayerNotificationManager.MediaDescriptionAdapter {
override fun getCurrentContentTitle(player: Player): String {
val window = player.currentWindowIndex
return "Title"
}
override fun getCurrentContentText(player: Player): String? {
val window = player.currentWindowIndex
return "Description"
}
override fun getCurrentLargeIcon(
player: Player,
callback: BitmapCallback
): Bitmap? = null
override fun createCurrentContentIntent(player: Player): PendingIntent? {
val window = player.currentWindowIndex
return null
}
}
}
这是我启动服务的方式 -
val intent = Intent(context, PodcastPlayerService::class.java)
val serviceBundle = Bundle()
serviceBundle.putParcelable("test", podcast)
intent.putExtra(ArgumentKeyAndValues.KEY_PODCAST, serviceBundle)
context?.let { Util.startForegroundService(it, intent) }
但是,当我这样做时,onStartCommand
不断被调用(我假设操作系统出于某种原因不断杀死我的服务并START_STICKY
强制它重新启动)并且没有任何反应。
如果我将媒体、通知管理器和侦听器代码放在onCreate
服务中,则可以正常工作。
我哪里错了?
解决方案
原来我两次启动前台服务-
ContextCompat.startForegroundService(this,
Intent(applicationContext, this::class.java))
startForeground(OtherConstants.PODCAST_NOTIFICATION_ID, notification)
推荐阅读
- sql-server - SSRS 从每个合并的数据集中查找缺失的项目
- r - 检查数据框中的字符串
- firebase - 在 Flutter 中的 Future 中添加列表项不返回任何项
- java - How to convert an XML structured-like object to a JSON string in Java?
- swift - 从带有图像附件的 'NSAttributedString' 的 html 演示文稿的数据中将字符串另存为 doc 无法显示图像
- c# - 从 Activity C# 之外的 OnClick 事件启动 Activity
- python - 如何使弹出窗口显示正常的文本翻译,而不是
? - git - 从 github repo 的主页中删除贡献者
- javascript - Why I cannot use an array with a set in javascript?
- javascript - 使用 Javascript 添加和显示列的内容