The Scene interface

The Scene interface describes the basic functionality for a screen. Firstly, it supplies a SceneKey property that can be used to identify separate instances. Next to that, it provides several lifecycle describing methods:

 1 interface Scene<V : Container> {
 2 
 3     val key: SceneKey get() = SceneKey.from(javaClass)
 4 
 5     fun onStart() {}
 6     fun onStop() {}
 7     fun onDestroy() {}
 8     
 9     fun attach(v: V) {}
10     fun detach(v: V) {}
11 }

The first three methods describe the Scene's own lifecycle:

  • onStart(): Called when the Scene is started;
  • onStop(): Called when the Scene is stopped;
  • onDestroy(): Called when the Scene gets destroyed.

These allow you to start or stop doing work at the appropriate times.
To be able to access the user interface, the Scene also provides the attach and detach methods:

  • attach(V): Attaches the Container of type V to the Scene;
  • detach(V): Detaches the Container of type V from the Scene;

onStart / onStop

These two methods mark the active stage of the Scene. You could for example choose to register to location updates when the Scene becomes active, and cancel the registration when the Scene becomes inactive:

 1 interface MyContainer : Container
 2 
 3 class MyScene(
 4     private val locationProvider: LocationProvider
 5 ): Scene<MyContainer> {
 6 
 7     private val listener = { location: Location? ->
 8         // Process location update
 9     }
10 
11     override fun onStart() {
12         locationProvider.registerLocationUpdates(listener)
13     }
14 
15     override fun onStop() {
16         locationProvider.unregisterLocationUpdates(listener)
17     }
18 }

attach / detach

These two methods give you access to the user interface. You can grab a reference to the Container instance in attach to be able to pass data to it. However, you must make sure to remove the reference in detach to prevent memory leaks. For example, if we expand on the previous example:

 1 interface MyContainer : Container {
 2 
 3     var location : Location?
 4 }
 5 
 6 class MyScene(
 7     private val locationProvider: LocationProvider
 8 ): Scene<MyContainer> {
 9 
10     private var view: MyContainer? = null
11 
12     private val listener = { location: Location? ->
13         view?.location = location
14     }
15 
16     override fun onStart() {
17         locationProvider.registerLocationUpdates(listener)
18     }
19 
20     override fun attach(v: MyContainer) {
21         this.view = v
22     }
23 
24     override fun detach(v: MyContainer) {
25         this.view = null
26     }
27 
28     override fun onStop() {
29         locationProvider.unregisterLocationUpdates(listener)
30     }
31 }

This implementation will start to listen to location updates as soon as the Scene becomes active. When a view is attached, the location updates will be passed on to it. When the view is detached, the reference to the view is removed, but the Scene will still listen to location updates. Finally, When the Scene becomes inactive, it will stop listening to location updates as well.

onDestroy()

onDestroy() will be called once and only once at the end of the lifetime of the Scene. When this method is called, the Scene must be regarded as destroyed and no more calls to its lifecycle methods will be made. You can use this callback to release resources if you already haven't done so.