media icon indicating copy to clipboard operation
media copied to clipboard

Implement LifecycleService in MediaSessionService and DownloadService

Open yschimke opened this issue 3 years ago • 5 comments

LifecycleOwner is a lifecycle aware option for Services. There is a base class LifecycleService which manages this, or you can implement LifecycleOwner and use ServiceLifecycleDispatcher

See https://developer.android.com/reference/androidx/lifecycle/LifecycleService https://developer.android.com/reference/androidx/lifecycle/ServiceLifecycleDispatcher

and https://www.daniweb.com/programming/mobile-development/tutorials/537446/android-native-how-to-implement-lifecycleowner-in-a-service

yschimke avatar Oct 17 '22 08:10 yschimke

Can you briefly educate me in how you would use the MediaSessionService in you app or library when it is lifecycle aware and dispatches the events accordingly?

I'm asking because onCreate/onDestroy is fairly simple in a service. What events are you interested in and what is depending on these? How would a media library service developer use the bind/start events?

marcbaechinger avatar Nov 04 '22 21:11 marcbaechinger

You can get a CoroutineScope for the current component (Service, Activity) such as

https://github.com/google/horologist/blob/10fb61ff97458dbbe004039eca2f94a320ac69da/media-sample/src/main/java/com/google/android/horologist/mediasample/di/PlaybackServiceModule.kt#L202-L208

    @ServiceScoped
    @Provides
    fun serviceCoroutineScope(
        service: Service
    ): CoroutineScope {
        return (service as LifecycleOwner).lifecycleScope
    }

Also instead of hardcoding events in onCreate, onDestroy - you can attach them to the lifecycle

https://github.com/google/horologist/blob/10fb61ff97458dbbe004039eca2f94a320ac69da/media-sample/src/main/java/com/google/android/horologist/mediasample/di/PlaybackServiceModule.kt#L266-L273

                (service as LifecycleOwner).lifecycle.addObserver(
                    object :
                        DefaultLifecycleObserver {
                        override fun onDestroy(owner: LifecycleOwner) {
                            it.release()
                        }
                    }
                )

Both really helpful when you have something like Hilt that means you create instances inside your DI modules, instead of directly in the Service implementation.

yschimke avatar Nov 05 '22 09:11 yschimke

If you follow the lead of Activities, the typical baseclass in a compose app is now

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        ContextAware,
        LifecycleOwner,
        ViewModelStoreOwner,
        ...

So this is basically adopting the same approach here.

yschimke avatar Nov 05 '22 09:11 yschimke

I think unfortunately there's always going to need to be a class cast in the Dependency Injection module here even if media3 provides an out of the box implementation of the LifecycleOwner, since Hilt's Service scoping only provides the platform Service class, not a LifecycleService.

It would also force the media3 libraries to expose the lifecycle components library to consumers, so I wonder if there's a way to do it in a composable way? Or through a custom listener for when the service is destroyed, similar to how a ViewModelScoped component in Hilt gets a listener binding for when the ViewModel is cleared.

I agree that this would be useful as I'm also looking at keeping the direct Service overriding code minimal and instead building/providing the dependencies to the Service as part of Dependency Injection and scoping things to the Service lifecycle from there

sampengilly avatar Dec 06 '23 06:12 sampengilly

Any news?

anonym24 avatar Feb 12 '24 16:02 anonym24