1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.lifecycle
17 
18 import android.app.Service
19 import android.os.Handler
20 
21 /**
22  * Helper class to dispatch lifecycle events for a Service. Use it only if it is impossible to use
23  * [LifecycleService].
24  *
25  * @param provider [LifecycleOwner] for a service, usually it is a service itself
26  */
27 public open class ServiceLifecycleDispatcher(provider: LifecycleOwner) {
28 
29     private val registry: LifecycleRegistry
30     private val handler: Handler
31     private var lastDispatchRunnable: DispatchRunnable? = null
32 
33     init {
34         registry = LifecycleRegistry(provider)
35         @Suppress("DEPRECATION")
36         handler = Handler()
37     }
38 
postDispatchRunnablenull39     private fun postDispatchRunnable(event: Lifecycle.Event) {
40         lastDispatchRunnable?.run()
41         lastDispatchRunnable = DispatchRunnable(registry, event)
42         handler.postAtFrontOfQueue(lastDispatchRunnable!!)
43     }
44 
45     /** Must be a first call in [Service.onCreate] method, even before super.onCreate call. */
onServicePreSuperOnCreatenull46     public open fun onServicePreSuperOnCreate() {
47         postDispatchRunnable(Lifecycle.Event.ON_CREATE)
48     }
49 
50     /** Must be a first call in [Service.onBind] method, even before super.onBind call. */
onServicePreSuperOnBindnull51     public open fun onServicePreSuperOnBind() {
52         postDispatchRunnable(Lifecycle.Event.ON_START)
53     }
54 
55     /**
56      * Must be a first call in [Service.onStart] or [Service.onStartCommand] methods, even before a
57      * corresponding super call.
58      */
onServicePreSuperOnStartnull59     public open fun onServicePreSuperOnStart() {
60         postDispatchRunnable(Lifecycle.Event.ON_START)
61     }
62 
63     /** Must be a first call in [Service.onDestroy] method, even before super.OnDestroy call. */
onServicePreSuperOnDestroynull64     public open fun onServicePreSuperOnDestroy() {
65         postDispatchRunnable(Lifecycle.Event.ON_STOP)
66         postDispatchRunnable(Lifecycle.Event.ON_DESTROY)
67     }
68 
69     /** [Lifecycle] for the given [LifecycleOwner] */
70     public open val lifecycle: Lifecycle
71         get() = registry
72 
73     internal class DispatchRunnable(
74         private val registry: LifecycleRegistry,
75         val event: Lifecycle.Event
76     ) : Runnable {
77         private var wasExecuted = false
78 
runnull79         override fun run() {
80             if (!wasExecuted) {
81                 registry.handleLifecycleEvent(event)
82                 wasExecuted = true
83             }
84         }
85     }
86 }
87