如何将 MVVM 与绑定服务一起使用?
How do I use MVVM with bound service?
我有一个绑定服务作为处理 exoplayer 的前台服务启动。
这是我的片段处理服务的方式-
@AndroidEntryPoint
class AudioPlayerFragment: Fragment() {
private var binding: AudioPlayerFragmentBinding by autoCleared()
private lateinit var podcast: Podcast
private lateinit var podcastPlayerService: PodcastPlayerService
private var isBound = false
private val connection = object: ServiceConnection {
override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
val binder = iBinder as PodcastPlayerService.LocalBinder
podcastPlayerService = binder.getService()
isBound = true
initPlayer()
}
override fun onServiceDisconnected(p0: ComponentName?) {
isBound = false
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = AudioPlayerFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
podcast = arguments?.getParcelable(ExtrasKeyAndValues.KEY_PODCAST)!!
binding.title.text = podcast.title
binding.description.text = podcast.description
startPodcastPlayerService(podcast)
binding.exoPlayerView.useController = true
binding.exoPlayerView.showController()
binding.exoPlayerView.controllerAutoShow = true
binding.exoPlayerView.controllerHideOnTouch = false
}
override fun onStart() {
super.onStart()
Intent(activity, PodcastPlayerService::class.java).also {
intent -> activity?.bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
initPlayer()
}
override fun onStop() {
activity?.unbindService(connection)
isBound = false
super.onStop()
}
private fun initPlayer() {
if (isBound) {
val player: SimpleExoPlayer = podcastPlayerService.getPlayerInstance()
binding.exoPlayerView.player = player
}
}
private fun startPodcastPlayerService(podcast: Podcast) {
val intent = Intent(context, PodcastPlayerService::class.java)
val serviceBundle = Bundle()
serviceBundle.putParcelable(ExtrasKeyAndValues.KEY_PODCAST, podcast)
intent.putExtra(ExtrasKeyAndValues.BUNDLE_PODCAST_SERVICE, serviceBundle)
context?.let { Util.startForegroundService(it, intent) }
}
}
问题是服务(显然)在 phone 轮换(配置更改)时重新启动。我如何以服务不重新启动但仅将其自身附加到片段及其 UI?
的方式构建我的应用程序
将它放在 ViewModel
中没有意义,因为建议避免将 android 框架相关的东西放在那里。
这里最好创建类似 VideoHelper
class 的内容,其中将包括所有与播放器相关的代码和初始化。包括控制播放器状态和其他相关事物的功能。参考你的问题 service is not restarted but just attaches itself to the fragment and its UI
,我记得我实现了在 onPause
或 onStop
中保存视频状态和进度的逻辑,并在 onResume
时将其恢复。基本上,您需要创建单独的 VideoHelper
函数,例如 getProgress
并在 onPause
或 onStop
中调用它,而您应该从 [=14] 中调用函数 setProgress
=] 并在设置之前检查它是否为空或 null。您可以随心所欲地保存进度 - 共享首选项或一些静态数据或其他任何内容。
我有一个绑定服务作为处理 exoplayer 的前台服务启动。
这是我的片段处理服务的方式-
@AndroidEntryPoint
class AudioPlayerFragment: Fragment() {
private var binding: AudioPlayerFragmentBinding by autoCleared()
private lateinit var podcast: Podcast
private lateinit var podcastPlayerService: PodcastPlayerService
private var isBound = false
private val connection = object: ServiceConnection {
override fun onServiceConnected(p0: ComponentName?, iBinder: IBinder?) {
val binder = iBinder as PodcastPlayerService.LocalBinder
podcastPlayerService = binder.getService()
isBound = true
initPlayer()
}
override fun onServiceDisconnected(p0: ComponentName?) {
isBound = false
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = AudioPlayerFragmentBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
podcast = arguments?.getParcelable(ExtrasKeyAndValues.KEY_PODCAST)!!
binding.title.text = podcast.title
binding.description.text = podcast.description
startPodcastPlayerService(podcast)
binding.exoPlayerView.useController = true
binding.exoPlayerView.showController()
binding.exoPlayerView.controllerAutoShow = true
binding.exoPlayerView.controllerHideOnTouch = false
}
override fun onStart() {
super.onStart()
Intent(activity, PodcastPlayerService::class.java).also {
intent -> activity?.bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
initPlayer()
}
override fun onStop() {
activity?.unbindService(connection)
isBound = false
super.onStop()
}
private fun initPlayer() {
if (isBound) {
val player: SimpleExoPlayer = podcastPlayerService.getPlayerInstance()
binding.exoPlayerView.player = player
}
}
private fun startPodcastPlayerService(podcast: Podcast) {
val intent = Intent(context, PodcastPlayerService::class.java)
val serviceBundle = Bundle()
serviceBundle.putParcelable(ExtrasKeyAndValues.KEY_PODCAST, podcast)
intent.putExtra(ExtrasKeyAndValues.BUNDLE_PODCAST_SERVICE, serviceBundle)
context?.let { Util.startForegroundService(it, intent) }
}
}
问题是服务(显然)在 phone 轮换(配置更改)时重新启动。我如何以服务不重新启动但仅将其自身附加到片段及其 UI?
的方式构建我的应用程序将它放在 ViewModel
中没有意义,因为建议避免将 android 框架相关的东西放在那里。
这里最好创建类似 VideoHelper
class 的内容,其中将包括所有与播放器相关的代码和初始化。包括控制播放器状态和其他相关事物的功能。参考你的问题 service is not restarted but just attaches itself to the fragment and its UI
,我记得我实现了在 onPause
或 onStop
中保存视频状态和进度的逻辑,并在 onResume
时将其恢复。基本上,您需要创建单独的 VideoHelper
函数,例如 getProgress
并在 onPause
或 onStop
中调用它,而您应该从 [=14] 中调用函数 setProgress
=] 并在设置之前检查它是否为空或 null。您可以随心所欲地保存进度 - 共享首选项或一些静态数据或其他任何内容。