[MUSIC] Welcome to part two in our lesson on programming bound services with messengers. After completing this part of the lesson, you'll know the steps used to program a client server app, which contains messengers that can currently generate a system-wide unique ID. In this app, a client, which is the uniqueIDGenActivity, and a server, which is the uniqueIDGenService, which is a bounce service, engage in a conversation by passing messages back and forth across a connection between processes on a local Android device. We'll now discuss the steps for programming the UniqueIDGen app. These steps generalize to programming other bound services, in addition to one use by the UniqueIDGen app. The activity pre-launches the bound service when the activity first starts to run, in other words before it actually sends any messages to the service. This behavior differs from a started service, which is launched on-demand when startService is called together with the intent that will be sent to the service. The bound service next initializes itself. For example, request messenger and handler objects can be allocated for later use. The activity is then connected to the bound service. This allows the activity to receive a messenger reference that it needs to engage in a conversation with the bound service. Next, the activity and the bound service interact by passing messages as part of their conversation. At some point, the bound service will be stopped after the last activity that's bound to it unbinds from the service. The service is then destroyed, and the resources it allocated are reclaimed by Android. We'll start by discussing the various programming steps required to launch a bound service. Components can call bindService to connect to a bound service. Activities and services can both connect to bound services. However, a broadcast receiver cannot connect to a bound service, since its life time is intentionally short. bindService is an asynchronous method call, so it won’t block the caller while the connection with the service is being established. An explicit intent is passed to bindService to identify the given service. Note how the makeIntent factory method defined in the UniqueIDGenService class runs in the context of the activity process, not in the context of the service process. A callback object is also passed to bindService, it's used to monitor the connection. The various hook methods on this object are dispatched when the service is connected and when the service is disconnected. You should define this callback object in the user interface thread of the activity or component, so its hook methods are dispatched in that thread. The service is launched via the Activator pattern if it isn't already running. We'll next describe programming steps involved in in initializing a bound service. The onCreate and onBind hook methods can be used to initialize a bound service. These hook methods are inherited from the Service class. The onCreate hook method can be used initialize service fields. For example, the UniqueIDGenService initializes its messenger and handler fields in the onCreate hook method. These fields could also be initialized when they are defined in the class itself, in which case onCreate may be a. The onBind hook method returns an IBinder, which enables the client and service to interact. A bound service must implement the onBind hook method to return something other than null, which is how the Android Activity Manager Service knows that it's actually a bound service, and not a started service. onBind returns an object that's typically initialized in onCreate or as a field in the class, as we just discussed. It returns this is an IBinder that the client uses to interact with the request handler. For example, a messenger object has a method called getBinder that returns a reference to the messenger that could be passed across process address spaces. onBind retrieves the IBinder when the first client binds to the service. Due to this caching, the intent that's passed to onBind isn't very useful. We'll now talk about the various programming steps that are needed to connect to a bound service. A callback-driven protocol is used to establish a connection between a client component and a bound service. The ServiceConnection class and the instances of this ServiceConnection class are used as targets of callbacks from the Android Activity Manager Service, which is used to monitor the state of a bound service. In particular, the onServiceConnected hook method is called back when the service is connected, and it returns a reference to an object that resides in the service. The onServiceConnected hook method runs in the context of the user interface thread. One of the parameters passed is an IBinder, which is the base interface for a remotable object, which means that this object's implementation might reside in a separate process, in which case, it's remotable, or it could actually be co-located with the same process where the client can We typically use this method to store our reference to some type of object that's passed back from the service. For example in the context of our Unique IDGen app, we store a reference the service's Messenger, in a field that's part of their activity. The onServiceDisconnected hook method is called back by the Activity Manager Service when a connection is lost. This typically happens when the process that's hosting the bound service crashes or is killed by the low memory killer. Note that the connection is actually not removed, and the Activity Manager Service will reconnect the client component and the service again by calling it's onServiceConnected method when the service is back up and running. What we in this particular example is we set the request messenger ref to null to indicate to the client activity that it can't make invocations to the service until the service connection have been re-established. We'll next discuss the programming steps needed to interact with bound services. Recall that a bound service allows clients to converse with the service. A conversation typically involves an exchange of data, between one of our clients, and a service. These interactions can be generic and message-oriented, such as using messengers and handlers for inter or intra-process communication, which is the main focus of the type of interactions we emphasized in this module, in this MOOC, or the interactions can also be type-specific and method-oriented. For example by using the Android Interface Definition Language for inter or intraprocess communication. AIDL is covered in the Mobile Cloud Computing with Android Specialization. Both of these approaches use the Android Binder IPC framework under the hood. The UniqueIDGen app uses two messengers to communicate. The request messenger, which is defined in the service, encapsulates a request handler. The request handler, in turn, is defined as a nested class within the UniqueIDGenService. After onBind returns the reference to the request messenger, the Activity Manager Service dispatches the onServiceConnected method, which runs in the context of the unique IDGenActivity. This method then stores the reference to the request messenger in a local field in the activity. generateUniqueID is called later when the user presses a button on the GUI. This method creates a request message that contains a reference to the reply messenger. It then sends that message to the request messenger that runs in the service process. The call to send on the request messenger's reference in the activity causes the handleMessage hook method in the RequestHandler running in the service to be called back. This method concurrently processes the request in a thread from a thread pool. As part of the processing, it extracts the reply messenger from the message, and uses it to return the unique ID back to the client. The client receives this returned value in the handleMessage hook method of it's reply handler, which is called back in the user interface thread of the activity. This method obtains the system-wide unique ID from the message and displays it to the user. Finally, we'll discuss the programming steps involved in stopping bound services. When a bound service is launched, its lifecycle depends on the component or components that access it. In particular, it typically doesn't run in the background indefinitely, but instead is managed automatically by the Activity Manager Service. An activity should therefore call unbindService, when it stops or when it's done interacting with a bound service. The onStop hook method of an activity is a common place to call unbindService. Android automatically unbinds the client components that are destroyed, even if unbindService is not called exclusively. However, it's a good idea to call unbindService as soon as a service is no longer needed, to clean up any resources that may otherwise be expended on a service that's not being accessed. When the last connected client calls unbindService, the service's onUnbind hook method is dispatched automatically by the Activity Manager Service. onUnbind returns false by default, which follows the normal shutdown protocol. In particular, the bound method is destroyed when no clients are bound to it. The onDestroy lifecycle hook method is dispatched when a bound service is being destroyed. This method typically cleans up any resources that were allocated dynamically. For example, we could shut down the thread pool and unique IDGenService. Note that if a bound service is also a start service, then the onUnbind hook method should return true. This is commonly referred to as a so called hybrid service. In this case, onRebind is called when new clients bind to a service. This concludes part two of our lesson on programming bound services with messengers. [MUSIC]