简体   繁体   English

如何将 MVVM 与绑定服务一起使用?

[英]How do I use MVVM with bound service?

I have a bound service that is started as foreground service for handling exoplayer.我有一个绑定服务,它作为前台服务启动,用于处理 exoplayer。

Here is how my fragment handles the service -这是我的片段处理服务的方式 -

@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) }
    }
}

The problem is that the service (obviously) restarts when the phone is rotated (config change).问题是服务(显然)在手机旋转(配置更改)时重新启动。 How do I architect my app in a way that the service is not restarted but just attaches itself to the fragment and its UI?如何以不重新启动服务而仅将自身附加到片段及其 UI 的方式构建我的应用程序?

Placing it in a ViewModel does not make sense because it is recommended to avoid putting android framework related stuff in there.将它放在ViewModel中没有意义,因为建议避免将与 android 框架相关的东西放在那里。

The best thing here to create something like VideoHelper class that will include all player related code and initialization.最好的办法是创建类似VideoHelper类的东西,该类将包含所有与播放器相关的代码和初始化。 Includes the function that will control the state of the player and other related things.包括将控制播放器状态和其他相关事物的功能。 Referring to your question service is not restarted but just attaches itself to the fragment and its UI as I remember I implemented the logic that saved the state and progress of the video in onPause or onStop and set it back when onResume .参考您的问题service is not restarted but just attaches itself to the fragment and its UI因为我记得我实现了在onPauseonStop中保存视频的状态和进度的逻辑,并在onResume时将其设置回来。 Basically, you need to create in separate VideoHelper functions like getProgress and call it in onPause or onStop and function setProgress that you should call from onResume and before setting it check if it not empty or null.基本上,您需要创建单独的VideoHelper函数,例如getProgress并在onPauseonStop和函数setProgress中调用它,您应该从onResume调用它,并在设置它之前检查它是否不为空或为空。 The progress you can save any way you want - shared preferences or some static data or anything else.您可以以任何方式保存进度 - 共享首选项或一些静态数据或其他任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使服务绑定到正确的活动实例? - How do I keep a service bound to the right activity instance? 如何在Android中使用MVVM将jsonObject发布到api中? - How do I Post jsonObject into api use MVVM in Android? 如何将 Xamarin.Essentials MediaPicker 与 MVVM 和 DataBinding 一起使用 - How do I use Xamarin.Essentials MediaPicker with MVVM and DataBinding 我为什么要使用绑定服务? - Why would I use a Bound Service? Android MVVM - 在哪里绑定到 Mediaplayer 绑定服务? - Android MVVM - Where to bind to a Mediaplayer bound service? XAMARIN Android 应用程序,如何在 MVVM 中获取已安装应用程序的列表作为服务? - XAMARIN Android App, how do I get a list of installed apps as a service in MVVM? 在Android上绑定服务与启动服务以及如何执行这两项操作 - bound service versus started service on Android and how to do both 我们如何知道某个服务是否已在绑定和未绑定的服务中停止? - How do we know if a service has stopped in a bound and unbound service? 如何使用 Android SpeechRecognizer 作为服务? - How do I use Android SpeechRecognizer as a service? 我如何在服务外使用getQsTile - How do i use getQsTile outside of the service
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM