From 2150553dc374204a1cb3033ed3fa65c2f22dd5e7 Mon Sep 17 00:00:00 2001
From: Scott Main AIDL (Android Interface Definition Language) is similar to other IDLs you might have
+worked with. It allows you to define the programming interface that both
+the client and service agree upon in order to communicate with each other and allows for
+interprocess communication (IPC). On Android, one process can not normally access the
+memory of another process. So to talk, they need to decompose their objects into primitives that the
+operating system can understand, and "marshall" the object across that boundary for you. The code to
+do that marshalling is tedious to write, so Android handles it for you with AIDL. Note: Using AIDL is necessary only if you allow clients from
+different applications to access your service for IPC and want to handle multithreading in your
+service. If you do not need to perform IPC across
+different applications, you should create your interface implementing a
+Binder or, if you want to perform IPC, but do not need to handle multithreading, then you
+should implement your interface using a Messenger. Before you begin designing your AIDL interface, be aware that calls on to an AIDL interface are
+direct function calls. You can not generally make assumptions about the thread in which the call
+will happen. What happens is different depending on whether the call is from a thread in the
+local process, or coming from a remote process. Specifically: You must define your AIDL interface in an {@code .aidl} file using the Java
+programming language syntax, then save it in the source code (in the {@code src/} directory) of both
+the application hosting the service and any other application that will bind to the service. When you build the projects containing the {@code .aidl} file, the Android SDK tools generate an
+{@link android.os.IBinder} class based on your AIDL interface (and saves the file in the {@code
+gen/} directory). This class defines the APIs you can call to perform RPC as an interface—you
+must implement the interface in your service. To create a bounded service using AIDL, follow these steps: This file defines the programming interface with method signatures. The Android SDK tools generate an interface in the Java programming language, based on your
+{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
+{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
+{@code Stub} class and implement the methods. Implement a {@link android.app.Service Service} and override {@link
+android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
+class. Caution: Any changes that you make to your AIDL interface after
+your first release must remain backward compatible in order to avoid breaking other applications
+that use your service. That is, because your {@code .aidl} file must be copied to other applications
+in order for them to access your service's interface, you must maintain support for the original
+interface. AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
+take parameters and return values. The parameters and return values can be of any type, even other
+AIDL-generated interfaces. The syntax for the {@code .aidl} file uses the Java programming language. The file defines a
+single interface and requires only the interface declaration and method signatures. By default, AIDL supports the following data types: All elements in the {@link java.util.List} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
+java.util.List} may optionally be used as a "generic" class (e.g. All elements in the {@link java.util.Map} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
+(such as those of the form
+{@code Map<String,Integer>} are not supported. The actual concrete class that the other side
+will receive will always be a {@link java.util.HashMap}, although the method will be generated to
+use the {@link java.util.Map} interface. You must include an {@code import} statement for each additional type not listed above, even if
+they are defined in the same package as your interface. When defining methods for your service interface, be aware that: Primitives are Caution: You should limit the direction to what is truly
+needed, because marshalling parameters is expensive. Here is an example {@code .aidl} file: Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
+build your application, the SDK tools will generate the binder class file in your project's
+{@code gen/} directory. The generated file name matches the {@code .aidl} file name, but with a
+{@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
+IRemoteService.java}). If you use Eclipse, the incremental build generates the binder class almost immediately. If you
+do not use Eclipse, then the Ant tool generates the binder class next time you build your
+application—you should build your project with When you build your application, the Android SDK tools generate a {@code .java} interface file
+named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
+that is an abstract implementation of its parent interface (for example, {@code
+YourInterface.Stub}) and declares all the methods from the {@code .aidl} file. Note: {@code Stub} also
+defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
+android.os.IBinder} (usually the one passed to a client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
+returns an instance of the stub interface. See the section Calling an IPC
+Method for more details on how to make this cast.
+
+
+
+Defining an AIDL Interface
+
+
+
+
+1. Create the .aidl file
+
+
+
+
+List<String>).
+The actual concrete class that the other side will receive will always be an {@link
+java.util.ArrayList}, although the method will be generated to use the {@link
+java.util.List} interface.
+
+
+in, out, or inout (see the example below).
+ in by default, and cannot be otherwise.
+// IRemoteService.aidl
+package com.example.android;
+
+// Declare any non-default types here with import statements
+
+/** Example service interface */
+interface IRemoteService {
+ /** Request the process ID of this service, to do evil things with it. */
+ int getPid();
+
+ /** Demonstrates some basic types that you can use as parameters
+ * and return values in AIDL.
+ */
+ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+ double aDouble, String aString);
+}
+
+
+ant debug (or ant
+release) as soon as you're finished writing the {@code .aidl} file, so that your code can
+link against the generated class.2. Implement the interface
+
+
To implement the interface generated from the {@code .aidl}, extend the generated {@link +android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods +inherited from the {@code .aidl} file.
+ +Here is an example implementation of an interface called {@code IRemoteService} (defined by the +{@code IRemoteService.aidl} example, above) using an anonymous instance:
+ +
+private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+ public int getPid(){
+ return Process.myPid();
+ }
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+};
+
+
+Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}), +which defines the RPC interface for the service. In the next step, this instance is exposed to +clients so they can interact with the service.
+ +There are a few rules you should be aware of when implementing your AIDL interface:
+Once you've implemented the interface for your service, you need to expose it to +clients so they can bind to it. To expose the interface +for your service, extend {@link android.app.Service Service} and implement {@link +android.app.Service#onBind onBind()} to return an instance of your class that implements +the generated {@code Stub} (as discussed in the previous section). Here's an example +service that exposes the {@code IRemoteService} example interface to clients.
+ +
+public class RemoteService extends Service {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // Return the interface
+ return mBinder;
+ }
+
+ private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+ public int getPid(){
+ return Process.myPid();
+ }
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+ };
+}
+
+
+Now, when a client (such as an activity) calls {@link android.content.Context#bindService +bindService()} to connect to this service, the client's {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the +{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()} +method.
+ +The client must also have access to the interface class, so if the client and service are in +separate applications, then the client's application must have a copy of the {@code .aidl} file +in its {@code src/} directory (which generates the {@code android.os.Binder} +interface—providing the client access to the AIDL methods).
+ +When the client receives the {@link android.os.IBinder} in the {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
+YourServiceInterface.Stub.asInterface(service) to cast the returned
+parameter to YourServiceInterface type. For example:
+IRemoteService mIRemoteService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Following the example above for an AIDL interface,
+ // this gets an instance of the IRemoteInterface, which we can use to call on the service
+ mIRemoteService = IRemoteService.Stub.asInterface(service);
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "onServiceDisconnected");
+ }
+};
+
+
+For more sample code, see the {@code +RemoteService.java} class in ApiDemos.
+ + + + + + + + +If you have a class that you would like to send from one process to another through +an IPC interface, you can do that. However, you must ensure that the code for your class is +available to the other side of the IPC and the class must support the {@link +android.os.Parcelable} interface, in order for the objects to be decomposed into primitives and +marshalled across processes by the Android system.
+ +There are five parts to making a class support the {@link android.os.Parcelable} protocol: +
CREATOR to your class which is an object implementing
+the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.If you are using a custom build process, do not add the {@code .aidl} file to your +build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.
AIDL will use these methods and fields in the code it generates to marshall and unmarshall +your objects.
+ +For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's +parcelable:
+ ++package android.graphics; + +// Declare Rect so AIDL can find it and knows that it implements +// the parcelable protocol. +parcelable Rect; ++ +
And here is an example of how the {@link android.graphics.Rect} class implements the +{@link android.os.Parcelable} protocol.
+ +
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public final class Rect implements Parcelable {
+ public int left;
+ public int top;
+ public int right;
+ public int bottom;
+
+ public static final Parcelable.Creator<Rect> CREATOR = new
+Parcelable.Creator<Rect>() {
+ public Rect createFromParcel(Parcel in) {
+ return new Rect(in);
+ }
+
+ public Rect[] newArray(int size) {
+ return new Rect[size];
+ }
+ };
+
+ public Rect() {
+ }
+
+ private Rect(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public void writeToParcel(Parcel out) {
+ out.writeInt(left);
+ out.writeInt(top);
+ out.writeInt(right);
+ out.writeInt(bottom);
+ }
+
+ public void readFromParcel(Parcel in) {
+ left = in.readInt();
+ top = in.readInt();
+ right = in.readInt();
+ bottom = in.readInt();
+ }
+}
+
+
+The marshalling in the {@code Rect} class is pretty simple. Take a look at the other +methods on {@link android.os.Parcel} to see the other kinds of values you can write +to a Parcel.
+ +Warning: Don't forget the security implications of receiving +data from other processes. In this case, the {@code Rect} will read four numbers from the {@link +android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of +values for whatever the caller is trying to do. See Security and Permissions for more +information about how to keep your application secure from malware.
+ diff --git a/docs/html/guide/topics/fundamentals/bound-services.jd b/docs/html/guide/topics/fundamentals/bound-services.jd new file mode 100644 index 0000000000000..e5d626c0799cc --- /dev/null +++ b/docs/html/guide/topics/fundamentals/bound-services.jd @@ -0,0 +1,675 @@ +page.title=Bound Services +parent.title=Services +parent.link=services.html +@jd:body + + +A bound service is the server in a client-server interface. A bound service allows components +(such as activities) to bind to the service, send requests, receive responses, and even perform +interprocess communication (IPC). A bound service typically lives only while it serves another +application component and does not run in the background indefinitely.
+ +This document shows you how to create a bound service, including how to bind +to the service from other application components. However, you should also refer to the Services document for additional +information about services in general, such as how to deliver notifications from a service, set +the service to run in the foreground, and more.
+ + +A bound service is an implementation of the {@link android.app.Service} class that allows +other applications to bind to it and interact with it. To provide binding for a +service, you must implement the {@link android.app.Service#onBind onBind()} callback method. This +method returns an {@link android.os.IBinder} object that defines the programming interface that +clients can use to interact with the service.
+ +As discussed in the Services +document, you can create a service that is both started and bound. That is, the service can be +started by calling {@link android.content.Context#startService startService()}, which allows the +service to run indefinitely, and also allow a client to bind to the service by calling {@link +android.content.Context#bindService bindService()}. +
If you do allow your service to be started and bound, then when the service has been +started, the system does not destroy the service when all clients unbind. Instead, you must +explicitly stop the service, by calling {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}.
+ +Although you should usually implement either {@link android.app.Service#onBind onBind()} +or {@link android.app.Service#onStartCommand onStartCommand()}, it's sometimes necessary to +implement both. For example, a music player might find it useful to allow its service to run +indefinitely and also provide binding. This way, an activity can start the service to play some +music and the music continues to play even if the user leaves the application. Then, when the user +returns to the application, the activity can bind to the service to regain control of playback.
+ +Be sure to read the section about Managing the Lifecycle of a Bound +Service, for more information about the service lifecycle when adding binding to a +started service.
+A client can bind to the service by calling {@link android.content.Context#bindService +bindService()}. When it does, it must provide an implementation of {@link +android.content.ServiceConnection}, which monitors the connection with the service. The {@link +android.content.Context#bindService bindService()} method returns immediately without a value, but +when the Android system creates the connection between the +client and service, it calls {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} on the {@link +android.content.ServiceConnection}, to deliver the {@link android.os.IBinder} that +the client can use to communicate with the service.
+ +Multiple clients can connect to the service at once. However, the system calls your service's +{@link android.app.Service#onBind onBind()} method to retrieve the {@link android.os.IBinder} only +when the first client binds. The system then delivers the same {@link android.os.IBinder} to any +additional clients that bind, without calling {@link android.app.Service#onBind onBind()} again.
+ +When the last client unbinds from the service, the system destroys the service (unless the +service was also started by {@link android.content.Context#startService startService()}).
+ +When you implement your bound service, the most important part is defining the interface +that your {@link android.app.Service#onBind onBind()} callback method returns. There are a few +different ways you can define your service's {@link android.os.IBinder} interface and the following +section discusses each technique.
+ + + +When creating a service that provides binding, you must provide an {@link android.os.IBinder} +that provides the programming interface that clients can use to interact with the service. There +are three ways you can define the interface:
+ +This is the preferred technique when your service is merely a background worker for your own +application. The only reason you would not create your interface this way is because +your service is used by other applications or across separate processes.
This is the simplest way to perform interprocess communication (IPC), because the {@link +android.os.Messenger} queues all requests into a single thread so that you don't have to design +your service to be thread-safe.
+To use AIDL directly, you must +create an {@code .aidl} file that defines the programming interface. The Android SDK tools use +this file to generate an abstract class that implements the interface and handles IPC, which you +can then extend within your service.
+Note: Most applications should not use AIDL to +create a bound service, because it may require multithreading capabilities and +can result in a more complicated implementation. As such, AIDL is not suitable for most applications +and this document does not discuss how to use it for your service. If you're certain that you need +to use AIDL directly, see the AIDL +document.
+ + + + +If your service is used only by the local application and does not need to work across processes, +then you can implement your own {@link android.os.Binder} class that provides your client direct +access to public methods in the service.
+ +Note: This works only if the client and service are in the same +application and process, which is most common. For example, this would work well for a music +application that needs to bind an activity to its own service that's playing music in the +background.
+ +Here's how to set it up:
+Note: The reason the service and client must be in the same +application is so the client can cast the returned object and properly call its APIs. The service +and client must also be in the same process, because this technique does not perform any +marshalling across processes.
+ +For example, here's a service that provides clients access to methods in the service through +a {@link android.os.Binder} implementation:
+ +
+public class LocalService extends Service {
+ // Binder given to clients
+ private final IBinder mBinder = new LocalBinder();
+ // Random number generator
+ private final Random mGenerator = new Random();
+
+ /**
+ * Class used for the client Binder. Because we know this service always
+ * runs in the same process as its clients, we don't need to deal with IPC.
+ */
+ public class LocalBinder extends Binder {
+ LocalService getService() {
+ // Return this instance of LocalService so clients can call public methods
+ return LocalService.this;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /** method for clients */
+ public int getRandomNumber() {
+ return mGenerator.nextInt(100);
+ }
+}
+
+
+The {@code LocalBinder} provides the {@code getService()} method for clients to retrieve the +current instance of {@code LocalService}. This allows clients to call public methods in the +service. For example, clients can call {@code getRandomNumber()} from the service.
+ +Here's an activity that binds to {@code LocalService} and calls {@code getRandomNumber()} +when a button is clicked:
+ +
+public class BindingActivity extends Activity {
+ LocalService mService;
+ boolean mBound = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to LocalService
+ Intent intent = new Intent(this, LocalService.class);
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+
+ /** Called when a button is clicked (the button in the layout file attaches to
+ * this method with the android:onClick attribute) */
+ public void onButtonClick(View v) {
+ if (mBound) {
+ // Call a method from the LocalService.
+ // However, if this call were something that might hang, then this request should
+ // occur in a separate thread to avoid slowing down the activity performance.
+ int num = mService.getRandomNumber();
+ Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /** Defines callbacks for service binding, passed to bindService() */
+ private ServiceConnection mConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ // We've bound to LocalService, cast the IBinder and get LocalService instance
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mBound = false;
+ }
+ };
+}
+
+
+The above sample shows how the client binds to the service using an implementation of +{@link android.content.ServiceConnection} and the {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback. The next +section provides more information about this process of binding to the service.
+ +Note: The example above doesn't explicitly unbind from the service, +but all clients should unbind at an appropriate time (such as when the activity pauses).
+ +For more sample code, see the {@code +LocalService.java} class and the {@code +LocalServiceActivities.java} class in ApiDemos.
+ + + + + +When you need to perform IPC, using a {@link android.os.Messenger} for your interface is +simpler than implementing it with AIDL, because {@link android.os.Messenger} queues +all calls to the service, whereas, a pure AIDL interface sends simultaneous requests to the +service, which must then handle multi-threading.
+For most applications, the service doesn't need to perform multi-threading, so using a {@link +android.os.Messenger} allows the service to handle one call at a time. If it's important +that your service be multi-threaded, then you should use AIDL to define your interface.
+If you need your service to communicate with remote processes, then you can use a +{@link android.os.Messenger} to provide the interface for your service. This technique allows +you to perform interprocess communication (IPC) without the need to use AIDL.
+ +Here's a summary of how to use a {@link android.os.Messenger}:
+ +In this way, there are no "methods" for the client to call on the service. Instead, the +client delivers "messages" ({@link android.os.Message} objects) that the service receives in +its {@link android.os.Handler}.
+ +Here's a simple example service that uses a {@link android.os.Messenger} interface:
+ +
+public class MessengerService extends Service {
+ /** Command to the service to display a message */
+ static final int MSG_SAY_HELLO = 1;
+
+ /**
+ * Handler of incoming messages from clients.
+ */
+ class IncomingHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SAY_HELLO:
+ Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+ /**
+ * Target we publish for clients to send messages to IncomingHandler.
+ */
+ final Messenger mMessenger = new Messenger(new IncomingHandler());
+
+ /**
+ * When binding to the service, we return an interface to our messenger
+ * for sending messages to the service.
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
+ return mMessenger.getBinder();
+ }
+}
+
+
+Notice that the {@link android.os.Handler#handleMessage handleMessage()} method in the +{@link android.os.Handler} is where the service receives the incoming {@link android.os.Message} +and decides what to do, based on the {@link android.os.Message#what} member.
+ +All that a client needs to do is create a {@link android.os.Messenger} based on the {@link +android.os.IBinder} returned by the service and send a message using {@link +android.os.Messenger#send send()}. For example, here's a simple activity that binds to the +service and delivers the {@code MSG_SAY_HELLO} message to the service:
+ +
+public class ActivityMessenger extends Activity {
+ /** Messenger for communicating with the service. */
+ Messenger mService = null;
+
+ /** Flag indicating whether we have called bind on the service. */
+ boolean mBound;
+
+ /**
+ * Class for interacting with the main interface of the service.
+ */
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // This is called when the connection with the service has been
+ // established, giving us the object we can use to
+ // interact with the service. We are communicating with the
+ // service using a Messenger, so here we get a client-side
+ // representation of that from the raw IBinder object.
+ mService = new Messenger(service);
+ mBound = true;
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ mService = null;
+ mBound = false;
+ }
+ };
+
+ public void sayHello(View v) {
+ if (!mBound) return;
+ // Create and send a message to the service, using a supported 'what' value
+ Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
+ try {
+ mService.send(msg);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to the service
+ bindService(new Intent(this, MessengerService.class), mConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+}
+
+
+Notice that this example does not show how the service can respond to the client. If you want the +service to respond, then you need to also create a {@link android.os.Messenger} in the client. Then +when the client receives the {@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()} callback, it sends a {@link android.os.Message} to the service that includes +the client's {@link android.os.Messenger} in the {@link android.os.Message#replyTo} parameter +of the {@link android.os.Messenger#send send()} method.
+ +You can see an example of how to provide two-way messaging in the {@code +MessengerService.java} (service) and {@code +MessengerServiceActivities.java} (client) samples.
+ + + + + +Application components (clients) can bind to a service by calling +{@link android.content.Context#bindService bindService()}. The Android +system then calls the service's {@link android.app.Service#onBind +onBind()} method, which returns an {@link android.os.IBinder} for interacting with the service.
+ +The binding is asynchronous. {@link android.content.Context#bindService +bindService()} returns immediately and does not return the {@link android.os.IBinder} to +the client. To receive the {@link android.os.IBinder}, the client must create an instance of {@link +android.content.ServiceConnection} and pass it to {@link android.content.Context#bindService +bindService()}. The {@link android.content.ServiceConnection} includes a callback method that the +system calls to deliver the {@link android.os.IBinder}.
+ +Note: Only activities, services, and content providers can bind +to a service—you cannot bind to a service from a broadcast receiver.
+ +So, to bind to a service from your client, you must:
+Your implementation must override two callback methods:
+When your client is destroyed, it will unbind from the service, but you should always unbind +when you're done interacting with the service or when your activity pauses so that the service can +shutdown while its not being used. (Appropriate times to bind and unbind is discussed +more below.)
+For example, the following snippet connects the client to the service created above by +extending the Binder class, so all it must do is cast the returned +{@link android.os.IBinder} to the {@code LocalService} class and request the {@code +LocalService} instance:
+ +
+LocalService mService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Because we have bound to an explicit
+ // service that is running in our own process, we can
+ // cast its IBinder to a concrete class and directly access it.
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "onServiceDisconnected");
+ mBound = false;
+ }
+};
+
+
+With this {@link android.content.ServiceConnection}, the client can bind to a service by passing +this it to {@link android.content.Context#bindService bindService()}. For example:
+ ++Intent intent = new Intent(this, LocalService.class); +bindService(intent, mConnection, Context.BIND_AUTO_CREATE); ++ +
Here are some important notes about binding to a service:
+Note: You should usually not bind and unbind +during your activity's {@link android.app.Activity#onResume onResume()} and {@link +android.app.Activity#onPause onPause()}, because these callbacks occur at every lifecycle transition +and you should keep the processing that occurs at these transitions to a minimum. Also, if +multiple activities in your application bind to the same service and there is a transition between +two of those activities, the service may be destroyed and recreated as the current activity unbinds +(during pause) before the next one binds (during resume). (This activity transition for how +activities coordinate their lifecycles is described in the Activities +document.)
+For more sample code, showing how to bind to a service, see the {@code +RemoteService.java} class in ApiDemos.
+ + + + + +
+Figure 1. The lifecycle for a service that is started +and also allows binding.
+When a service is unbound from all clients, the Android system destroys it (unless it was also +started with {@link android.app.Service#onStartCommand onStartCommand()}). As such, you don't have +to manage the lifecycle of your service if it's purely a bound +service—the Android system manages it for you based on whether it is bound to any clients.
+ +However, if you choose to implement the {@link android.app.Service#onStartCommand +onStartCommand()} callback method, then you must explicitly stop the service, because the +service is now considered to be started. In this case, the service runs until the service +stops itself with {@link android.app.Service#stopSelf()} or another component calls {@link +android.content.Context#stopService stopService()}, regardless of whether it is bound to any +clients.
+ +Additionally, if your service is started and accepts binding, then when the system calls +your {@link android.app.Service#onUnbind onUnbind()} method, you can optionally return +{@code true} if you would like to receive a call to {@link android.app.Service#onRebind +onRebind()} the next time a client binds to the service (instead of receiving a call to {@link +android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind +onRebind()} returns void, but the client still receives the {@link android.os.IBinder} in its +{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback. +Below, figure 1 illustrates the logic for this kind of lifecycle.
+ +For more information about the lifecycle of an started service, see the Services document.
+ + + + diff --git a/docs/html/guide/topics/fundamentals/services.jd b/docs/html/guide/topics/fundamentals/services.jd new file mode 100644 index 0000000000000..df1eacee50295 --- /dev/null +++ b/docs/html/guide/topics/fundamentals/services.jd @@ -0,0 +1,860 @@ +page.title=Services +parent.title=Application Fundamentals +parent.link=index.html +@jd:body + +A {@link android.app.Service} is an application component that can perform +long-running operations in the background and does not provide a user interface. Another +application component can start a service and it will continue to run in the background even if the +user switches to another application. Additionally, a component can bind to a service to +interact with it and even perform interprocess communication (IPC). For example, a service might +handle network transactions, play music, perform file I/O, or interact with a content provider, all +from the background.
+ +A service can essentially take two forms:
+ +Although this documentation generally discusses these two types of services separately, your +service can work both ways—it can be started (to run indefinitely) and also allow binding. +It's simply a matter of whether you implement a couple callback methods: {@link +android.app.Service#onStartCommand onStartCommand()} to allow components to start it and {@link +android.app.Service#onBind onBind()} to allow binding.
+ +Regardless of whether your application is started, bound, or both, any application component +can use the service (even from a separate application), in the same way that any component can use +an activity—by starting it with an {@link android.content.Intent}. However, you can declare +the service as private, in the manifest file, and block access from other applications. This is +discussed more in the section about Declaring the service in the +manifest.
+ +Caution: A service runs in the +main thread of its hosting process—the service does not create its own thread +and does not run in a separate process (unless you specify otherwise). This means +that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 +playback or networking), you should create a new thread within the service to do that work. By using +a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the +application's main thread can remain dedicated to user interaction with your activities.
+ + +A service is simply a component that can run in the background even when the user is not +interacting with your application. Thus, you should create a service only if that is what you +need.
+If you need to perform work outside your main thread, but only while the user is interacting +with your application, then you should probably instead create a new thread and not a service. For +example, if you want to play some music, but only while your activity is running, you might create +a thread in {@link android.app.Activity#onCreate onCreate()}, start running it in {@link +android.app.Activity#onStart onStart()}, then stop it in {@link android.app.Activity#onStop +onStop()}. Also consider using {@link android.os.AsyncTask} or {@link android.os.HandlerThread}, +instead of the traditional {@link java.lang.Thread} class. See the Processes and +Threading document for more information about threads.
+Remember that if you do use a service, it still runs in your application's main thread by +default, so you should still create a new thread within the service if it performs intensive or +blocking operations.
+To create a service, you must create a subclass of {@link android.app.Service} (or one +of its existing subclasses). In your implementation, you need to override some callback methods that +handle key aspects of the service lifecycle and provide a mechanism for components to bind to +the service, if appropriate. The most important callback methods you should override are:
+ +If a component starts the service by calling {@link +android.content.Context#startService startService()} (which results in a call to {@link +android.app.Service#onStartCommand onStartCommand()}), then the service +remains running until it stops itself with {@link android.app.Service#stopSelf()} or another +component stops it by calling {@link android.content.Context#stopService stopService()}.
+ +If a component calls +{@link android.content.Context#bindService bindService()} to create the service (and {@link +android.app.Service#onStartCommand onStartCommand()} is not called), then the service runs +only as long as the component is bound to it. Once the service is unbound from all clients, the +system destroys it.
+ +The Android system will force-stop a service only when memory is low and it must recover system +resources for the activity that has user focus. If the service is bound to an activity that has user +focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. +Otherwise, if the service was started and is long-running, then the system will lower its position +in the list of background tasks over time and the service will become highly susceptible to +killing—if your service is started, then you must design it to gracefully handle restarts +by the system. If the system kills your service, it restarts it as soon as resources become +available again (though this also depends on the value you return from {@link +android.app.Service#onStartCommand onStartCommand()}, as discussed later). For more information +about when the system might destroy a service, see the Processes and Threading +document.
+ +In the following sections, you'll see how you can create each type of service and how to use +it from other application components.
+ + + +Like activities (and other components), you must declare all services in your application's +manifest file.
+ +To decalare your service, add a {@code <service>} element +as a child of the {@code <application>} +element. For example:
+ ++<manifest ... > + ... + <application ... > + <service android:name=".ExampleService" /> + ... + </application> +</manifest> ++ +
There are other attributes you can include in the {@code <service>} element to +define properties such as permissions required to start the service and the process in +which the service should run. See the {@code <service>} element +reference for more information.
+ +Just like an activity, a service can define intent filters that allow other components to +invoke the service using implicit intents. By declaring intent filters, components +from any application installed on the user's device can potentially start your service if your +service declares an intent filter that matches the intent another application passes to {@link +android.content.Context#startService startService()}.
+ +If you plan on using your service only locally (other applications do not use it), then you +don't need to (and should not) supply any intent filters. Without any intent filters, you must +start the service using an intent that explicitly names the service class. More information +about starting a service is discussed below.
+ +Additionally, you can ensure that your service is private to your application only if +you include the {@code android:exported} +attribute and set it to {@code "false"}. This is effective even if your service supplies intent +filters.
+ +For more information about creating intent filters for your service, see the Intents and Intent Filters +document.
+ + + +If you're building an application for Android 1.6 or lower, you need +to implement {@link android.app.Service#onStart onStart()}, instead of {@link +android.app.Service#onStartCommand onStartCommand()} (in Android 2.0, +{@link android.app.Service#onStart onStart()} was deprecated in favor of {@link +android.app.Service#onStartCommand onStartCommand()}).
+For more information about providing compatibility with versions of Android older than 2.0, see +the {@link android.app.Service#onStartCommand onStartCommand()} documentation.
+A started service is one that another component starts by calling {@link +android.content.Context#startService startService()}, resulting in a call to the service's +{@link android.app.Service#onStartCommand onStartCommand()} method.
+ +When a service is started, it has a lifecycle that's independent of the +component that started it and the service can run in the background indefinitely, even if +the component that started it is destroyed. As such, the service should stop itself when its job +is done by calling {@link android.app.Service#stopSelf stopSelf()}, or another component can stop it +by calling {@link android.content.Context#stopService stopService()}.
+ +An application component such as an activity can start the service by calling {@link +android.content.Context#startService startService()} and passing an {@link android.content.Intent} +that specifies the service and includes any data for the service to use. The service receives +this {@link android.content.Intent} in the {@link android.app.Service#onStartCommand +onStartCommand()} method.
+ +For instance, suppose an activity needs to save some data to an online database. The activity can +start a companion service and deliver it the data to save by passing an intent to {@link +android.content.Context#startService startService()}. The service receives the intent in {@link +android.app.Service#onStartCommand onStartCommand()}, connects to the Internet and performs the +database transaction. When the transaction is done, the service stops itself and it is +destroyed.
+ +Caution: A services runs in the same process as the application +in which it is declared and in the main thread of that application, by default. So, if your service +performs intensive or blocking operations while the user interacts with an activity from the same +application, the service will slow down activity performance. To avoid impacting application +performance, you should start a new thread inside the service.
+ +Traditionally, there are two classes you can extend to create a started service:
+The following sections describe how you can implement your service using either one for these +classes.
+ + +Because most started services don't need to handle multiple requests simultaneously +(which can actually be a dangerous multi-threading scenario), it's probably best if you +implement your service using the {@link android.app.IntentService} class.
+ +The {@link android.app.IntentService} does the following:
+ +All this adds up to the fact that all you need to do is implement {@link +android.app.IntentService#onHandleIntent onHandleIntent()} to do the work provided by the +client. (Though, you also need to provide a small constructor for the service.)
+ +Here's an example implementation of {@link android.app.IntentService}:
+ +
+public class HelloIntentService extends IntentService {
+
+ /**
+ * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
+ * constructor with a name for the worker thread.
+ */
+ public HelloIntentService() {
+ super("HelloIntentService");
+ }
+
+ /**
+ * The IntentService calls this method from the default worker thread with
+ * the intent that started the service. When this method returns, IntentService
+ * stops the service, as appropriate.
+ */
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() < endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+}
+
+
+That's all you need: a constructor and an implementation of {@link +android.app.IntentService#onHandleIntent onHandleIntent()}.
+ +If you decide to also override other callback methods, such as {@link +android.app.IntentService#onCreate onCreate()}, {@link +android.app.IntentService#onStartCommand onStartCommand()}, or {@link +android.app.IntentService#onDestroy onDestroy()}, be sure to call the super implementation, so +that the {@link android.app.IntentService} can properly handle the life of the worker thread.
+ +For example, {@link android.app.IntentService#onStartCommand onStartCommand()} must return +the default implementation (which is how the intent gets delivered to {@link +android.app.IntentService#onHandleIntent onHandleIntent()}):
+ +
+@Override
+public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+ return super.onStartCommand(intent,flags,startId);
+}
+
+
+Besides {@link android.app.IntentService#onHandleIntent onHandleIntent()}, the only method +from which you don't need to call the super class is {@link android.app.IntentService#onBind +onBind()} (but you only need to implement that if your service allows binding).
+ +In the next section, you'll see how the same kind of service is implemented when extending +the base {@link android.app.Service} class, which is a lot more code, but which might be +appropriate if you need to handle simultaneous start requests.
+ + +As you saw in the previous section, using {@link android.app.IntentService} makes your +implementation of a started service very simple. If, however, you require your service to +perform multi-threading (instead of processing start requests through a work queue), then you +can extend the {@link android.app.Service} class to handle each intent.
+ +For comparison, the following example code is an implementation of the {@link +android.app.Service} class that performs the exact same work as the example above using {@link +android.app.IntentService}. That is, for each start request, it uses a worker thread to perform the +job and processes only one request at a time.
+ +
+public class HelloService extends Service {
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+
+ // Handler that receives messages from the thread
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+ @Override
+ public void handleMessage(Message msg) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() < endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ // Stop the service using the startId, so that we don't stop
+ // the service in the middle of handling another job
+ stopSelf(msg.arg1);
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ // Start up the thread running the service. Note that we create a
+ // separate thread because the service normally runs in the process's
+ // main thread, which we don't want to block. We also make it
+ // background priority so CPU-intensive work will not disrupt our UI.
+ HandlerThread thread = new HandlerThread("ServiceStartArguments",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+
+ // Get the HandlerThread's Looper and use it for our Handler
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+
+ // For each start request, send a message to start a job and deliver the
+ // start ID so we know which request we're stopping when we finish the job
+ Message msg = mServiceHandler.obtainMessage();
+ msg.arg1 = startId;
+ mServiceHandler.sendMessage(msg);
+
+ // If we get killed, after returning from here, restart
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // We don't provide binding, so return null
+ return null;
+ }
+
+ @Override
+ public void onDestroy() {
+ Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
+ }
+}
+
+
+As you can see, it's a lot more work than using {@link android.app.IntentService}.
+ +However, because you handle each call to {@link android.app.Service#onStartCommand +onStartCommand()} yourself, you can perform multiple requests simultaneously. That's not what +this example does, but if that's what you want, then you can create a new thread for each +request and run them right away (instead of waiting for the previous request to finish).
+ +Notice that the {@link android.app.Service#onStartCommand onStartCommand()} method must return an +integer. The integer is a value that describes how the system should continue the service in the +event that the system kills it (as discussed above, the default implementation for {@link +android.app.IntentService} handles this for you, though you are able to modify it). The return value +from {@link android.app.Service#onStartCommand onStartCommand()} must be one of the following +constants:
+ +For more details about these return values, see the linked reference documentation for each +constant.
+ + + +You can start a service from an activity or other application component by passing an +{@link android.content.Intent} (specifying the service to start) to {@link +android.content.Context#startService startService()}. The Android system calls the service's {@link +android.app.Service#onStartCommand onStartCommand()} method and passes it the {@link +android.content.Intent}. (You should never call {@link android.app.Service#onStartCommand +onStartCommand()} directly.)
+ +For example, an activity can start the example service in the previous section ({@code +HelloSevice}) using an explicit intent with {@link android.content.Context#startService +startService()}:
+ ++Intent intent = new Intent(this, HelloService.class); +startService(intent); ++ +
The {@link android.content.Context#startService startService()} method returns immediately and +the Android system calls the service's {@link android.app.Service#onStartCommand +onStartCommand()} method. If the service is not already running, the system first calls {@link +android.app.Service#onCreate onCreate()}, then calls {@link android.app.Service#onStartCommand +onStartCommand()}.
+ +If the service does not also provide binding, the intent delivered with {@link +android.content.Context#startService startService()} is the only mode of communication between the +application component and the service. However, if you want the service to send a result back, then +the client that starts the service can create a {@link android.app.PendingIntent} for a broadcast +(with {@link android.app.PendingIntent#getBroadcast getBroadcast()}) and deliver it to the service +in the {@link android.content.Intent} that starts the service. The service can then use the +broadcast to deliver a result.
+ +Multiple requests to start the service result in multiple corresponding calls to the service's +{@link android.app.Service#onStartCommand onStartCommand()}. However, only one request to stop +the service (with {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}) is required to stop it.
+ + +A started service must manage its own lifecycle. That is, the system does not stop or +destroy the service unless it must recover system memory and the service +continues to run after {@link android.app.Service#onStartCommand onStartCommand()} returns. So, +the service must stop itself by calling {@link android.app.Service#stopSelf stopSelf()} or another +component can stop it by calling {@link android.content.Context#stopService stopService()}.
+ +Once requested to stop with {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}, the system destroys the service as soon as +possible.
+ +However, if your service handles multiple requests to {@link
+android.app.Service#onStartCommand onStartCommand()} concurrently, then you shouldn't stop the
+service when you're done processing a start request, because you might have since received a new
+start request (stopping at the end of the first request would terminate the second one). To avoid
+this problem, you can use {@link android.app.Service#stopSelf(int)} to ensure that your request to
+stop the service is always based on the most recent start request. That is, when you call {@link
+android.app.Service#stopSelf(int)}, you pass the ID of the start request (the startId
+delivered to {@link android.app.Service#onStartCommand onStartCommand()}) to which your stop request
+corresponds. Then if the service received a new start request before you were able to call {@link
+android.app.Service#stopSelf(int)}, then the ID will not match and the service will not stop.
Caution: It's important that your application stops its services +when it's done working, to avoid wasting system resources and consuming battery power. If necessary, +other components can stop the service by calling {@link +android.content.Context#stopService stopService()}. Even if you enable binding for the service, +you must always stop the service yourself if it ever received a call to {@link +android.app.Service#onStartCommand onStartCommand()}.
+ +For more information about the lifecycle of a service, see the section below about Managing the Lifecycle of a Service.
+ + + +A bound service is one that allows application components to bind to it by calling {@link +android.content.Context#bindService bindService()} in order to create a long-standing connection +(and generally does not allow components to start it by calling {@link +android.content.Context#startService startService()}).
+ +You should create a bound service when you want to interact with the service from activities +and other components in your application or to expose some of your application's functionality to +other applications, through interprocess communication (IPC).
+ +To create a bound service, you must implement the {@link +android.app.Service#onBind onBind()} callback method to return an {@link android.os.IBinder} that +defines the interface for communication with the service. Other application components can then call +{@link android.content.Context#bindService bindService()} to retrieve the interface and +begin calling methods on the service. The service lives only to serve the application component that +is bound to it, so when there are no components bound to the service, the system destroys it +(you do not need to stop a bound service in the way you must when the service is started +through {@link android.app.Service#onStartCommand onStartCommand()}).
+ +To create a bound service, the first thing you must do is define the interface that specifies +how a client can communicate with the service. This interface between the service +and a client must be an implementation of {@link android.os.IBinder} and is what your service must +return from the {@link android.app.Service#onBind +onBind()} callback method. Once the client receives the {@link android.os.IBinder}, it can begin +interacting with the service through that interface.
+ +Multiple clients can bind to the service at once. When a client is done interacting with the +service, it calls {@link android.content.Context#unbindService unbindService()} to unbind. Once +there are no clients bound to the service, the system destroys the service.
+ +There are multiple ways to implement a bound service and the implementation is more +complicated than a started service, so the bound service discussion appears in a separate +document about Bound Services.
+ + + +Once running, a service can notify the user of events using Toast Notifications or Status Bar Notifications.
+ +A toast notification is a message that appears on the surface of the current window for a +moment then disappears, while a status bar notification provides an icon in the status bar with a +message, which the user can select in order to take an action (such as start an activity).
+ +Usually, a status bar notification is the best technique when some background work has completed +(such as a file completed +downloading) and the user can now act on it. When the user selects the notification from the +expanded view, the notification can start an activity (such as to view the downloaded file).
+ +See the Toast Notifications or Status Bar Notifications +developer guides for more information.
+ + + +A foreground service is a service that's considered to be something the +user is actively aware of and thus not a candidate for the system to kill when low on memory. A +foreground service must provide a notification for the status bar, which is placed under the +"Ongoing" heading, which means that the notification cannot be dismissed unless the service is +either stopped or removed from the foreground.
+ +For example, a music player that plays music from a service should be set to run in the +foreground, because the user it explicitly aware +of its operation. The notification in the status bar might indicate the current song and allow +the user to launch an activity to interact with the music player.
+ +To request that your service run in the foreground, call {@link +android.app.Service#startForeground startForeground()}. This method takes two parameters: an integer +that uniquely identifies the notification and the {@link +android.app.Notification} for the status bar. For example:
+ ++Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), + System.currentTimeMillis()); +Intent notificationIntent = new Intent(this, ExampleActivity.class); +PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); +notification.setLatestEventInfo(this, getText(R.string.notification_title), + getText(R.string.notification_message), pendingIntent); +startForeground(ONGOING_NOTIFICATION, notification); ++ + +
To remove the service from the foreground, call {@link +android.app.Service#stopForeground stopForeground()}. This method takes a boolean, indicating +whether to remove the status bar notification as well. This method does not stop the +service. However, if you stop the service while it's still running in the foreground, then the +notification is also removed.
+ +Note: The methods {@link +android.app.Service#startForeground startForeground()} and {@link +android.app.Service#stopForeground stopForeground()} were introduced in Android 2.0 (API Level +5). In order to run your service in the foreground on older versions of the platform, you must +use the previous {@code setForeground()} method—see the {@link +android.app.Service#startForeground startForeground()} documentation for information about how +to provide backward compatibility.
+ +For more information about notifications, see Creating Status Bar +Notifications.
+ + + +The lifecycle of a service is much simpler than that of an activity. However, it's even more important +that you pay close attention to how your service is created and destroyed, because a service +can run in the background without the user being aware.
+ +The service lifecycle—from when it's created to when it's destroyed—can follow two +different paths:
+ +The service is created when another component calls {@link +android.content.Context#startService startService()}. The service then runs indefinitely and must +stop itself by calling {@link +android.app.Service#stopSelf() stopSelf()}. Another component can also stop the +service by calling {@link android.content.Context#stopService +stopService()}. When the service is stopped, the system destroys it..
The service is created when another component (a client) calls {@link +android.content.Context#bindService bindService()}. The client then communicates with the service +through an {@link android.os.IBinder} interface. The client can close the connection by calling +{@link android.content.Context#unbindService unbindService()}. Multiple clients can bind to +the same service and when all of them unbind, the system destroys the service. (The service +does not need to stop itself.)
These two paths are not entirely separate. That is, you can bind to a service that was already +started with {@link android.content.Context#startService startService()}. For example, a background +music service could be started by calling {@link android.content.Context#startService +startService()} with an {@link android.content.Intent} that identifies the music to play. Later, +possibly when the user wants to exercise some control over the player or get information about the +current song, an activity can bind to the service by calling {@link +android.content.Context#bindService bindService()}. In cases like this, {@link +android.content.Context#stopService stopService()} or {@link android.app.Service#stopSelf +stopSelf()} does not actually stop the service until all clients unbind.
+ + +Like an activity, a service has lifecycle callback methods that you can implement to monitor +changes in the service's state and perform work at the appropriate times. The following skeleton +service demonstrates each of the lifecycle methods:
+ + +
+Figure 2. The service lifecycle. The diagram on the left +shows the lifecycle when the service is created with {@link android.content.Context#startService +startService()} and the diagram on the right shows the lifecycle when the service is created +with {@link android.content.Context#bindService bindService()}.
+
+public class ExampleService extends Service {
+ int mStartMode; // indicates how to behave if the service is killed
+ IBinder mBinder; // interface for clients that bind
+ boolean mAllowRebind; // indicates whether onRebind should be used
+
+ @Override
+ public void {@link android.app.Service#onCreate onCreate}() {
+ // The service is being created
+ }
+ @Override
+ public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
+ // The service is starting, due to a call to {@link android.content.Context#startService startService()}
+ return mStartMode;
+ }
+ @Override
+ public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()}
+ return mBinder;
+ }
+ @Override
+ public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
+ // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
+ return mAllowRebind;
+ }
+ @Override
+ public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()},
+ // after onUnbind() has already been called
+ }
+ @Override
+ public void {@link android.app.Service#onDestroy onDestroy}() {
+ // The service is no longer used and is being destroyed
+ }
+}
+
+
+Note: Unlike the activity lifecycle callback methods, you are +not required to call the superclass implementation of these callback methods.
+ +By implementing these methods, you can monitor two nested loops of the service's lifecycle:
+ +The {@link android.app.Service#onCreate onCreate()} and {@link android.app.Service#onDestroy +onDestroy()} methods are called for all services, whether +they're created by {@link android.content.Context#startService startService()} or {@link +android.content.Context#bindService bindService()}.
If the service is started, the active lifetime ends the same time that the entire lifetime +ends (the service is still active even after {@link android.app.Service#onStartCommand +onStartCommand()} returns). If the service is bound, the active lifetime ends when {@link +android.app.Service#onUnbind onUnbind()} returns.
+Note: Although a started service is stopped by a call to +either {@link android.app.Service#stopSelf stopSelf()} or {@link +android.content.Context#stopService stopService()}, there is not a respective callback for the +service (there's no {@code onStop()} callback). So, unless the service is bound to a client, +the system destroys it when the service is stopped—{@link +android.app.Service#onDestroy onDestroy()} is the only callback received.
+ +Figure 2 illustrates the typical callback methods for a service. Although the figure separates +services that are created by {@link android.content.Context#startService startService()} from those +created by {@link android.content.Context#bindService bindService()}, keep +in mind that any service, no matter how it's started, can potentially allow clients to bind to it. +So, a service that was initially started with {@link android.app.Service#onStartCommand +onStartCommand()} (by a client calling {@link android.content.Context#startService startService()}) +can still receive a call to {@link android.app.Service#onBind onBind()} (when a client calls +{@link android.content.Context#bindService bindService()}).
+ +For more information about creating a service that provides binding, see the Bound Services document, +which includes more information about the {@link android.app.Service#onRebind onRebind()} +callback method in the section about Managing the Lifecycle of +a Bound Service.
+ + + +To learn how to query data from the system or other applications (such as contacts or media +stored on the device), continue with the Content Providers +document.
diff --git a/docs/html/images/fundamentals/service_binding_tree_lifecycle.png b/docs/html/images/fundamentals/service_binding_tree_lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..46d2df50e85a3fa60396a28e1371f900033df1e2 GIT binary patch literal 69225 zcmXt9V{~L)v`ji3+ngjFPHatV+qP|UV%w9<#J25BJh82bHL+fQ@2&Ua{OG&Z>CG zhZ;>Kmb&`LJmeI1?cps=MQXK0m8ynzGUEM0fr+Y*I`o)W>hKp%B`G*`X?ewUj!_M^ zlh=ofLF@Nr17GBIrkt??#U8)s+iVV7y~g@7bA=UsTXZnlOz?9zj&rdDa&}!`k&y>( zK4;c+c)8PW{vzqDhNJUFfy=ClCFa*DoHa^-&y87=W?|;0pr;sO{%(_=$&|rFPtmp* zOTj&qtXK9M7dvMTG3zN*DjBq_QFBQyljcA&IP;cmUN%e!eiL1frBD~E(B#hbpUdud zaVNC79xI%ypDfpsY|)|-92?U(#Dht{10(539yRDEX@Q)#vCYRV{OaM;v>DQ|W?1~N zB%`&qwt~&h2E4yVstfFp9g33&g6!K9T&vH$O{QT#EMJavyQ%Q@^+mKil=O~Ym`fBt zZM>tdmDS(l{J;+|9~GYIS3o{5`a`vk4JrA%)BTLo^Kt_U7DZ@%v%|eomD=vv>{mC) z=wcz^&=RhR7kJGw20e3ly*sEYAu&>|P-1;*!&YxMhTl9_G{~x6k;;W-Ql~Mze%r_S zk}kdLfXFaFrI?G^C-JNiRfi-2RLB=VUjORY^Gr3|A{v1b7Z<4l zv3GQ=TXjut%)4|$yK)^XI5AUkZrD}~bC2~msn=r_G#h0G@>zyvTlb3xG!X`v>JRM^ z+Qq7C5^}k&iO;_btR;W 6yw>Lj}Q bAc^j;*{| zvtWrF_A?;fjgjp#^AaMh)BSN}UV(#3dpa_s=Fp8kQ-~=n)xdD2=59%3rEzV4LX+-V zcG}rE2(MOt+G_`s7iPrIy%?sQhQ3s!bibQ|pK7$uKlr>^9iE?e6NwQokb{pj__V%> z_L-vfiJpYCG}Q%2*=7{SL^4mc?dy}z08RJUr||-_C|0>$D2lLK8uEWoFWa~`sc0<_ zF&p*CGIfXAr?U?$Yl=HmaI;WGeO76emP;vyD9ZwsOPUY_oH4?>P;kxj5-FlojaM;* z)3QiqB7( t%03t|7McIH{pv za?3{cA9IIL@@%r9Lbxf8 lYRKVY|L`W; z3?C*sx-*!UAKA2mx`XngOAe*5$6Yejaf**BY;3)K$H&y&o7>yy6l#?!DB*z~Ogt|H z)9ZQ)>OZuFGriN*X^L~RET2*;t;A%)JfV~_G-(idY^NzE{?<;zlpu>6Z6j**7?lxt z*dSRGe{6Fo1`~$-PNxI;fC(mw5CkT`PP#4&O(8Q(+hZVB!}yt4F!LcuxK`89|GpoV zWN4WRNtBb#TBYtKN4?=d {udQ=rECI5zbbiK&bL)u!cfJy?mv+WX|;l61^7_j-5UOC zWS9!YH&j{;q~%RbSSADQjzo#DC^)G`+H3q^?cMB)-T>1E4_MiA-W`BmW`@EAl1s$a zwJ`eS4pMhyX5!&FhJsLSV{(p;FXR+TJ*aFsSm#WiOcSQ^_?xdZom~S@czcLd88htB#G(&W}#t;?=%v3Ym-|+sTdhnxZA;?zQA; z;P!I5$6eC|LyywQ@l+@DK5qH02;P D}|AX;gs@x?e` zK~IB6mPhDqYKJOA+SwI=jxS+wZJ}=MBSk-H)gde^W#S_%&|WnW)ZOEx7ikdN`KiN$ z3h$a!Dr?l$)&EnK5kE)*-)1X9@>229d{kWN9T7cYw*CaJ1cnD$k_p-KxBax|)(#WZ zoDq1fx_ihLjS{$DP<8CS$BBnsnJ4=rEhjhhf#_E=h>*u$)Yh<;ZPPq0$W8I*x?8Sv z5hF10GDAbZ8U*Tp3!O@~AxI+o=I)-x$z0_=kp*Tk@X^m;otndS700!8ea~^dY^IT* z;I^u| G$wGJ}81%Y4WK#_uWkBCrZMdv&6&(RgJM;JD-aa30)j?qfHh z5c0Lh_tBv)8VZI^qsocC_2JG!5c)hf^pV?(V6Dgh73@)+Q?Jy}w4Kv9aiwM^yK+S_ z2M{F$#gJTq#romV(Etx(^XEb0!%ui6k#66|JQh=!8kAqsQ9I|jC3#N$*;!ferF (;|JgB#wxX!$3E%EY$+& z_Xha;`E`XAZ*UT3e{Y2Rd>R$}^Yxs@T~|PVGILn~8oaNqwElDr0 t9qcLs0gS^ zq6N{vPzsjU8for!7S%fP0KhY bmjK>Xt!7ElBIWTX%Tzdi! zutW-RAO779?5uGk2B*L*VR1~@c3N9pJby EOFuws j)_Spc5 zeg1;z^#i~v#i=IzyZKVuayoquCoXkg>GY c_u0WA za{EnEIyAU>$%9~58wvjwEfp6RyPqu~Yuf%LlxN!~^ A8eX9syvKVkMwXD`U u+#xy_vm|Z(8DtKh%*~pUl4ydj9=F102Z&v z0+JMcmZ;Iw^{!J-hs&Xiooqjkr(5Qd)2=)l)A#k@Y)8#8m7>9<-ioF~I7_61SOptI z!DI@0nQF%O$iz_U!Oo=hR^tU8etzoQfWAte4wo3I3TypAb2GC(Wd#)#j2b&P8~LwW z{=GL{U#PX}UvbtWowJ*7^waks;octB9hr3^`_I4*6?u=Pmr#t31AzD@ovp63nk-0j zE8zXb*j18lS`(W`h)`kQ%QZCw5P+_dO-2fj@nn}~X&jeqmS$byvdhU>9#W~E#Yi=v zMq@6dt&yp!wZzKil<@d(UU5)>!(d2vdh9ZrY^PaK7?V(OZhrozBtJ3HsG12i=(k9x z5QJlo=cYR@J ZJa_pgydDEYD z6iNOL_LMSJ_sDbAXooFQ{?BWU4thoh*p&>t@OCM$G`MF5uc4s#)j>}L)EN;H* Z%srAj6@s-=`E-*J!-Hz`_#7 zeaks;B&x2i_J6-$zCnm*_J8>|g0Cer0q1q0Y6SN9D0sFKB;p7bSq;u>s6lmspC8jd zczx@jb-~E;V?nllAL^*#kEOudwdnHsQ{Tj6E|06yGAxN-kacd#+Tp5M_X7>HVNIxV zZvS^!- BKNh<8?nh;J>hBfChYrK?aLrjPD^JBOZWLRGrNttzF9y&=zc? zGl#`S{Wu(EnDjmz$EGjJ7YzIW>j5w9#yYHt5wJbo=SLOc?^)9N1*dicbslE*P$vSt zDMm^Drhkv%Qg7P(T);qA%@kChJXJ4nvpQ`f>YkUND2HwdUw{l~S!fZit{V4 |K 7roc=l-mWkB)q4`m(wzt=_Dl zq4{yL^0yr~QF-~~*W@HDtgaQGlx{LPxz_Uzl_9#U{Kl|l20Q&PMs4(7qr0O;BA)!rDOfshY3mq|szX&j zlRZsbb<^<@-Zp39x6`=FeShNTvu(>yV-Se-W?~ih(9mCb%U!X;%HRkDpPjdP_N$ zyz*6Zh;d!`QQG#gDpEg5U&bvO3WL>O&v3&&IN)3Ys}{BRmFtv8yRJPqr+CqI;E;WR zu+iu~991J}$obcA71ai3ZTeA}$q;_Z4SH4m4swBj`<6IFqk}6xE=coW(2fDzWH!gy zP!uM2ybBoWP2FdSj}(4<3sXfv2m`=k6MOAI`byO|AVH!)&d-NLeqJ~RvdKCRDXM2D z!l@vfonno>jinz{g=|ckE##?aIo8*Vb!Iovn_*H}rm6p)8;Yb#U0iZ4N-hCK^?4-9 zWv9c<)ukzEf`WhWB^!{^r5ut{?M!EB6yM%Qr>OS69m!s{a2E?1P>NT4{X)sDA!QP* zmzPElM9(S#SZbuWI2T|C$57*{Ez(kuh7VRV%+I7Pwn}AF0X7$iw6oX|-MoRPJY#7; zj%KA2v2co9CsRVJ8agWU4k+NQRodCpY#qtg=mwp&fyO32IBUnLJ4EfgVd{jD06s#Q zda@<5AnT0|_cNn+#3hO `faqLtUOGHFpypGL3QF|XW3>UHr #7kwls1N);L1 zqA?&Gyf&2-eudLUVCnBo=krzRF)-8Nb#AQYE^*u4-Caop%u}SRwt3y`HCfN^Jnn!k zzw`_f9tO!i+kAi~z2+$vWhPJ_4plv$mysO4k;-LMugP4JLJZ5{HmxSAb2D)IH>veq zs2gh8(Gi14$hYTT?8s}$n;6DxYzwcB3>i2F$E5=5E^ddw6_x9=CChV|1w! 9Zd8eWlhWLkd^^$o8Ep8F58A;478Df3lL(@$10wr`qA0~4 z&sV=sa#K6~{R29`Z!UtH7(}Z>gVg-WGyJ&Xk;crrpb45FABghzN-O> XlE+=t0 z;^}J`?12?eSh5|f+~iLqor!BqKM+U}^MgH+^M2^^F-mJ=KZj%1d36GDx4*Ea0>YK^ z<~pwjo3hN7b+PmmQK^ZU{-9FzEmIhX3A !4EDSO9E#Fa-I>>F?b^?n_UBkrm}b;#@H(xDF_cu^L=63?fs z7RpOpQe8e=E-4D#wq7xaugg5v=G6xm^%mtXI#*Zo7)t$qB{?uv4D{X_`K#WrV6GY% zY=b`e`ThhFbH1LLorofBDD8b1g~AVM^DV2W;!chjB28tKJju$OO``kCRJ(LCO|tP7 zje!#M>#azsdg(;wu`078JhD{c#g@*+% )fUKdC9Yno=LiG~}YZE&rbdXc<<+y^4&SKr8w?`<1c#;EcrU*~&-kU+kc!v^ myuJ6=w6x+;??_A7G)ijL-L9bZ_-MdTJv zMNND_J-^fseqs=anK&TAN~gSszEiI7h{U9sySyp@X;iE$(9&m>#b^%wIOh`SlgJ4L zp${-a^)AX)(n^rn7?RW$zrDY}l$*UdVC2P txN4uIbNR%#TV@#H_JbH{2EPy zXxrDhTciKEsdVYlTxx9Ww>NY>%N+OaLIVH`38x+eUn6cc&-WL1@PMcibH(R!y|q^M z`Fd}>>w(5;*roW#J1yA4rJvLr6b}5NlRZN+^?=;3kIAr05{oOQFbHB_a*`T?g>q%+ zPb*(`(j#X41&>_XyGZ7LzykcNgM=DD%0iC1|5QfIwiw{`jFGkbjl`g&`c&L|plWH= z<`b?J3)&$9)@?VGm07LS8G}c(B)QD{2i#pOY{ 4hwhe?d{DLN_IBbXk>7a{|QLTbv*bt+NJGM zbpalTM?=gzU8p%-q}qFG)hv|TR-iXcIk2@L==vRp^!}7-HZ9XuZywHa*J)073jF^# zN)Q{ml_{mBb`$y1C{vm4SCJsYg*E;SYe>5*E-!ei=93a0cS_%-mnWbb;>CBg16*@v z^Ho~(V@u|H=AU$iN4SXrFMEOFkhU?lM9Qr`uBkK8T{4o1ChY&sUBiPUL4VR^6g&eI z^WmMp&$(jDq*ch|QKd8B+B1%}vleCqE&b#iE1xzvqDEs-Ov2Jowt;U5o1Ku|Fl{i~ zGZyMLefZO*c9P7}T}nyCXqbN%1Ya7@JIG}t)VlP? R z0*AcWozr7^f0iVhM~g{Y)6`K$kxp0dAhC=)smLeVu#ai!g3zgp-o5x#4cS>_)k|q6 z<#rW2(SLDg3EF7rCT2tMPK=qbx<2cU ;(j+z4qBBaq*((rxj>E&W@REapF4!2a>qAf;NgJ8K8yfgLkB zMLEy}Wx8XGhb=W1Qm%(Mcjh~b)knllL2@ajb8(-xNOUOMgC3nC24#_D$?UfiX@R0~ zilBu3{8ERyVCy1N^C6H+YlFhFIjllWW$fYt89)w)VPJnK#~`NbdC>9GXt`(`!X_bq zr_Te@(j}{P6g6i!*9JX0h1C^d9Ls0_y;(ghS7NUl*kpILJ(S<4NTlqXLKWN2b|eOY z3T4iGpHQ}I##Io-1C3FkI7Fk}uDvnqlB<3^ 7L?+Z;M2UQy(^fmrs zsTL+JYw5>B0qyH5m6hWVAWik*Q)_5Qsu&Fjmo@uZ@vYrXx@O pAW_9fe6{%Bh+5fOtFPNVUzW9b{kSA<&j#_znpth5g63qjG%Vc z($I*71p!7Hy_=OM0gklhA4cmoUQ7i7ow_5>m|FNywiAn^*3-d)qZWMu;}nfhmZaK0 z9;a!wUYK-dR)tXv(^x&fr~hTVYhgcZJ{$CJJ`STW6}f!SG>L4%d!cNKah&jU??|kw z8i=q+cvRK&JVR0B=LbX*IG|4IXtsa;P-mU2;dH&1C=P5gJ|9y4#nJE&Np5rGM4q#f zPT_Z(1s9ws24zFkJQ=`tMzhe&b7TK`Hl?DSKgaGbUJ+w *3J0?B5yp4>uXpV?>kV2Eu9qbXSypyVzY)T4DgH)dd8*8y%nupuq#P6ywys&G ztz88T=%oiW=&XhJ+&ph-@oI_maPQPy9QLDw_k|(?+C$q}EVGgl+_%136r5`st%!r% z*CLs;T;7}_J;wSLq(%uFYq??NBOFxSo|xuwphKDx$ dYi_oY>Bkw*wQ0ZP;hm3O7V8v~PZ_Q3dHg&>(5a$dZk z@+FV$S`benJ4z%Qsum9F-BzbVSNGq77P>dBCL{?g0lu4V(NCs(i$8Vl!SY^saB8xy zw_z;1BPSNp)3nLVzY>zH3#JS(>aPzd@LOFfcd=GOl|iBV)WOF%Qz6vA*&$`kKtAoO z?Vk-+G@#jCJxnblxHi0CaE`7Q9653#Cq;wP$?F3fi?IRj7i%2gT-2hb;negrBNJ0= zI$&Z3?I#?!*4Q)GA(zn9>T5oDMU?!yT-~XdGL&ke-&RIC`{Z8L=plcmY}?PGg5&go zw_4olWub;Yr^HG;oOOLnRkLkAo$HDdHpLy#J}qF;S2mTH?kB*@t>SAl8*mXG|BM42 z|I`_cJMi0CNX goP>_haMjX T{?K?iV}Txw+@dD>X-pg+`KPuTOtd?7i9+-=XL!Qvu2wKaG0(K8(Wx#84wfi z@IO;a$YAeiO{K=^iz-9Z!?Z#dV3k>0wUx ^=5B3znTB4$8iSWVwc=* zArUm!(4azPR{ x51N^z=gP#|Y%V?c|1zR06!-w4$`$1R@7Td9n;Ht z >a#SfY= zZKkb3$kSr*vgwI4BIc2|O)HHlb0s;i3=L4s;Mzjhj=`a0_%&Vs%L*>%(B6uyRP Vze6Z_M`l2j5V~fOB79U;Mt(Jg83@(&8V(s{{}h07amQ zzy!&T{_qrMSeJcAZKSe6LiH{ma9Y?C3^JDQ#I(v?4#C>)V}|0{7GgUVM2>cy1`-sY z3Alo?a r9D-iIw=5g(1 zj3Ms)`BPL>XXA|-Aj(d?b?(M6ny>Mv^plefEI>JQBbjL|WXn0B#tLmA4MhmkI^O8Fm^@)dv#Ok=n*MefycFl=tNdvoVfI zWPx)1E#$-HqeBggxm9ghM%Z#=>Br2&O%#nv%KsT|)q;y9mx#IjXoX{FPA~uvOTIa! z6b|ENmwmGplr)1L$55-q-5}KQ5%PH27=<&1gGm1QUB_w2eZgUdtC@Mj#sacyVM_a; z0GK`!#Rjd@@z{$qDkPZWq^I>?2GdjX)0jTTexbA}IQyq$arFH=;ngNH?BCZ~R$x7V z(QryQ34%~iC1QhPPuqAz68f#P$lK%iqb8Yz%IsxF$X+^LjQjagBg0W{1D894MdAl& zM++D}8NjBV+3R#ktJS5;E}*4LtDULXAfSthiT}JpM>EFV2cEedmgd9v7viI#H%fu% z{7QOFwT%|=07L-$(gU}&)t9vBGVJx}HtVz+H}UfjdtS~_3FnlS#V$vlAA7J`vd@Es z`w>X+sHh3K0_Iq(9;mmf6TL45UF(r($*r6M0mCDUh$c!D7X2+YHOgZ8d95LZ7|nJU zYp5-WZ8zV4?r{pBAr~6BwxL1=o0^8%qU=N3qE*B^(igf*4m(Wm3w$k;^&A?l-D+_T zR$Pd_`=+9uJGH!z*=grmnDF=7qBY5M0M@fr-Q{8y=R!+X^?$uWSLs7ZuEZi=(f{}S zir9r!HQP-&xP0TZ>wE@b@yJKQ$Vd>uygyv%_eNmJ0GWM1?Q|>yhwQ(hKM)`2CyfX+ ztu}*}-O2RhnV`S>$NSU)rDZLuXIEgc05wv>OKRk?HK2Z6tmB08r*9)b90f@pVcyjR z(Z$uZfx8uY;6RT^A*E!1+ohu wOdGmA%Zs yvS?o z^nK0Af&w}hD){A3sxPE=M`lVAGYh}$OLr)5@Q+k&Qo2bjvMHyk9F@e95RT+*^0cF$ zWbtt&dS9J9s4$H}R6)DM0p|MJnCv+&hDtNVjV3k8osCb9S&S5OE-)U;FhHFPwl03H zX&XAgCj^2EHo>J^xdbKM?<9>fHSF64+9I_v1S1;AY3Y9@7};hei>KN2!x(Y@+3Y*1 zt}a52hkv?UgTjv<;CbAe5) &+> z$h;Wb{xv3YDzj4BB3ZIhxo$(bYc(&4plX}U^pBfS5@)R*)6w{z9(%UQ?BM4 hT5MyrkW5>qK@mJ{&Mdqov- o3$YpICPd7@e2-!K!)a(;RjNk2lvWGlQ~VYKrm zeWpu`x-eK8dD;v8TofqW^J$a1@&|5(%iEt9JDssKN9#HK4^iJ3P+1$cn`?5Djmb6H zc2kpWOtx*?c1^Y>+qP{@w(DE-p7Wjar$6nz*Lv2&`_cjxA-wBM%-AacdY0yR_bvjH z-g>>+ZYrC%M#2#g&|)ra>Xfy)-5Q&jod6Q-tn~E1YM -0KC%jEg#NgGn<)k4*2v~J><1A=(KpJv zJwJcB68436Rnc0&RWLp>#|{iNk*~wWrZZ>8`0w-#tH{U0RhE<#T6{-` YgoC=hR!R{0WQSOJ6T=0AY4`)d->`R4< xDXH*<&VNK;ERRci0o=J(1k!dd M@i_#27dO7#RYRE^4DdIQ?ngUp9z1+hLgc#AOWmo20?=Qc9 z#^~F^*`is4mPI5ZX4STjRzsP~GJHPng&+^~@Qc$^_z!1);DrE4ADEj7nBq_%n`ph+ zBP1R)u(Pbg`)zr@PMAl(>7&z=Hv4h%d@^7`! yC2FT2)?}Y@C5K`Xd!Z0)COZVclDVF9seYE~ zs!34F9Vgt2u-uULwacWYhPi9l=H*h2%{wfhO%$zTvTV;w@N0c@p #F}!}SV$058g mD_e;6RfX& z1^Xs_B&tR3a>SYkISR;WK%ys_NWV(h+0{-AR8qrC?WxVzm4%)%n;07>Cnh#`Za(OI ztBB{iM=0{1h{}0I)=VZcm7u9cbVi)6dC+rkf#_jo78PbLkl4Y0k Hl;yoo%vTSTH7hJih6oO3RXcEUWVQN%q_bW7*zX3P>XQ)Aq+0>cQQg`2 zn`a*>1GXQ$x||DhI4K5!LG|2fASq+Me8IeSW<@$x-|`P81OympXAvI1_xcJvA&+ZK zYpeU&a_wZ*u*?fq>2=(Q3<>#wzAo4Y9$0J8gCNXJ#Hwd3^Q<8Yg4!Q8*dkEro2IV| zD#--2)J=kESQdZgvGi#oS?q8VX2=!r6Ai2O^;Gu%E|epZT*w%{^%Y5dx#Ti@OSH9a zB84l0$>j5L2jILSD%we8Q*_XFUw*)6mE-lW^0?)*Wp13o?EA$3ag9`~b|&|(&&*9n zQ}X{Xu3ef?00T=V(!}a$7x@Wa1S(M-R!%lXu0A<^^7!rd((;YiuaX%BgTUna{q)R3 zN$acap2>~l-E`wxjS9i-5JGR;&jun3oc^0u7{BT1>HdC^%r9djBRx>ZnoZW6WxqVx zsp#oHZ^q~W2iWQ7+Y!H?UvL0SbXj-D$vj%eV?R{9vdZhI!CoycD+8(LM>uU>E_6ly zi8Q$R826*-8xa^U^R&ZdF{ZFr5*tWvN8=vXY22;q1ejVWeDn6L%={MtMD_II1 zOS!u>P>Q8~Ho&4CT4DLy&clnBaycGPn|n`<=1zE-a8{`CFco-vKHxKOU+!B@LS0fX zTjTsz-lyNHtG>$dq2H>vEHMQ)v9_I<`bp8>!C )STuz? z@f99gB+M*6?X5=_R`q&t#UMpeFY+p9e|j0)fr9tD``;T~ihe5z`dF*;GBujiI0oy( z5wd{jTh_m2GP~=xJ-OTO5*xcRML)(ytGwTvN@ZaP k*@x5JC5zAKK~jlC{l7zUn8YO0Y`N|VW>GN*#!&Q2<_Ze zk)5L6>lZeDee2jm8Y%Rz@ 8XD?$d*}rqL@g~XMn*>Cr#xP#*9A0-{xu@cfH4V)!oyYwauJ%R)T!b-AjOXM zg>`ljmO2t&4d7<8=62O7=SY_oiSv3JgKO%}k?_U){2`_Vak !Sp_6fhh{y;9;2{lB#UKoBauF3Fkl^ z%>TTPT6}ToNa%}*&&A?)WB9l; ;3K(w>V>z%n+;CU=4U(tL68& z#0vw2Vng4hlLm36z!&!`b}+uvNX~LP1k8&1;balEc;4B%ExY;Y+X&77Zfitwm$@ zj;L0h6mf52?bNg2Mxt21wf3QccSc9AL2qTnMC1Q{ceXNh903@-@F_jIIA*bC@IjcA znE6cl^XvUKr>Xb+ySwX({ZiS`p;8$-#)Uy^7^gWO6h^=Cj1>L?tYHS~2e7_h|A z9L<;{{)b}=oWejne1#ppId0jhtDFmdR>hNuNo_^@84@uF;oXT{1gZ-gD6cD&jlWrc z#A l@E7_BYQkoNtl%sO~TMxnE`-4=#@SAb0Ypr|~WiaiWFWN?E1o zr43A7%eK=DH^l1*XyKr})n=9UL;VtoNsTaWbmtOn^S_Kq<8WSXf=WoILRqdZ6CXVV z#X53cuE#t;WkjN|)o@cvQZc^|n}}055IIJ*TnWa5O4xkHq~Qtoed7jAsCW%s2rvS* zu>#zxt$VqPDyq~LVY+&zKO!1s92b(5Nr@Pm^EOV!ERX+a>|WYr4$r(Y6#ovkBR7!0 zXqsf_AjNu~H@8YCN_YHg9&}TrTWqb5(22uVHk}S3F1(a$UC+keJmmd sl@Xo+7op$<%?f0rryC6?Jp=$ z2T_2}Z%f0JM6mb58yfYIYyLIN<(e9zC<;|H|Jyz>=K1EYC&%(fGgfxKuKl*LH1l@M z({mAHfyJ -DB%`hUjzx z#^k2y5#JYDsWg~Z$oN^Sh$1?kG-b7-SyQw++C0m?I$0T hlSxB |ZTqyr>hUa?d89SQlUEIcE!(u}djOT85QJIFtiKeNAURc#q%?N42OOZbon=9B zVP@>8A%Z( ~~cFP+WX`%3oKvFb<+uPlkqDHr$)o0awVPUcrR zZt}9a^?eAPZ~l0R3igO~w%OnirAm-gg{9M$LDUE)@1(>L6x{=YsM=)=kbmiv!*GH` zQpxwc5JT_&N~))(#@gS&geTxZ9u$HFDi#2&-Ca(nY?+~%C%TG@JZ@fn1wo_M$Ro^0 z@7wozgPvdi*uJ00C3O6-UW`s44P$nfa0t*J=o;|`7o(&(4V{K*^ zWA_7pxYuc_C&>o-^Z6|+NCfv+thcvSsVFLwO9Mtdl}cW9#g`ErA;X`-Es$b4)&?nG zzb*{O+7Sg5jAx9ZUd3e6CZ5w(mU5=nXeED)XjKh*0?MeE>RI`*&l3bis2JU@=c%Mm z4?@@R f8#FG|J4FaI(+Gs8adGq4sP2+ z3=aOug BOmqe!+lMtvj)}Yv&_86a?8rM$`mF}GObq&=GS>!BD3JvHG*N%;pE?09 zL9UXdmrmR4WY&i1OBlXLI7LWsr|LK%?$tdKHj}Z;o1>8bn|FsBR7CjIQ&EpGT2ea^ zg=!;-mKRi~>?Lcn%sHzim{OAA#?Ly4Fb #JP*%kxOLe5MF!hq;+WSm#kTzN5hX4W@32&e9X-2*s)eQ1^n8y6n5T2R1i zH#D;1S=TN~MN|EcQcWyr7hATi3=}!yrMjZdkKr@ocCZRg4|uqgKB3EYr=WepB$d-2 zPS??)&G3Sw$J^aH%wN>A-*n8PWQr?GX{R( ln2NrI{IWYC)BWro6QBF`+XSyu z(p-|!E>ps6x5{VOHonXABK-o=hA;S;ME9G|BP{X3jd|9^TTc|&jKbI1>JZ=kqb#|v zKK%D5`*{W?Z`H6mlr}xrS&YY{jCN9AWgWRSCnw z@Nv(3>S_-9;>CiI48g2lVK4(F)FqoS7&x$Fd*@t!A-=0o hOP+QK69zA++)OG1Bvq$Q5lYgi$zhkA!{{q?JjxxBJqzP9ac;#;tot ztWGlYJ&9*b4e|gr)0hmI_)`K2`{^=N0v!*#JmCAZy4IKawrb3MKq}*LckEX#Sa;TS zMC2O-<4VF)%zNHK2JD(1QYTAFs;7F-9Lvo&OYxCAGyS76gbO^t_dMoBrk#ogA# ze&p=U<6K+TJw1m6FdAikT|;e@zAgbT{;A~DPDO}Fl1&3*p4`>Ww+5Ymf2ZbtnHp7| z3R$}mog_HcunJk5pw&EBmcRz02oija41wc>p9%^L;uka47)BtMCU7Rkb&yo#EdUzc zG;@>_gMr)FTBD?}x%4Mk`V>D$1##t78r;bGc%4fz9 j>c{e%42H$T>fxk z=C@YV{2t^h9f-+nUXPErXHak`R}=_hq)|97=o6McodiBiR5OP@#;&Fo%W}xH_&MRg zjU*0=C2Ad7@c;Ho)31J_5g1u~UaM`1c-IIyOpvC511y=ltY74q!>~NOys}EdmM v0p{;egVFajM}oB`6Wv}z&UL2#IQimR Q%(Ujh||ez&|*Yk0Z?qUMnbEgh!Rmy z90AE47c2F}@)!#X3xHu?US1xaWQk}Sp&C<~ e6upWsgJNI`OH1rS$46YpzD^gV*E(he#LnbY4 z7p)PSy^Q1!kR=j{S_z?H4R%b$b0 ^(f)UEm|e!sweUM~e^?0+9)L|KuIqU% zYLg%eS5u=YBMRI%Z#$5-;ltktA_@M3*uUJ4D4+klx)%zTzWu7VO1sVbv29Dg-pI IzxJX54AHaXfAW;!`FSb~n>L^8FLo3q4lYqz? 6;g^Nw2@S? zFtLW!?P3C}9)bTxV_JND3ynd6SZ+Qwlr=<#gqyP99=lLvu`8! v)0=6`>9n*E%1C5N zpX=8!3PHs8C1%g4H{cuUu(;CnKE^}Di5}?{8c|RO@qDR_9`*N1t4HQ#pBhZe)Dbvd ztdL!sR` _L^rl^%O|KXkAK+wR!EoMRE}lV*vK5TJE1SZ%l_22@cfx&FRrAoyOY zHM)3F7W!0H{y-V#z6^9y@#hSR-(OCxbK(PDBgUFvKMJd1?#zAGPC%qb6nIVerEPLS zDx^&8(ZqmJ#r`J_=-Wg_Iz7%!T#<__wqL%3xdI_(TxuNcurZ{ebmF>jAox~9z;%ji zb3y8w6-JRmc<0-TX@eq!OuEq8p_`m%6oC2o3!oH|X{?Ux97S>sXcn9;^%{`HxC&-d zz+tn3AT=kT?Bv37!&R8;;RQgR6e~(Nd +zj~uZ{C?T0!>GQF{_A(0<1Jv}ZtRTcL4!P@sj)&^uT6XiRw?cqaBH_~ z9nOtHw$l^k(ZARgNWT!56ert{rSCrOQ0kMPma4v3vK@?b`nMVn!F6O#>{py}2d}T2 znq$dEq4Y^Fy{Guxz(yi3hPa&`EH#7H7|zYt+z(XV nbn$w?ek}-u8@?(e zhKjT8C5{`d^Bs;jqU(u{54jCy{-}{+P&$jynf$f1X6w@{#af^o{zle6{9=xBvrg{_ zE~j&&{^+TrT2!PuM _Ll8RazIU<1K^)5N)toh@?rV;xr_6NP`g2xBPk*&R z051OP`^TK@h&IA(`kQ ZJ& zYYml@^HK0BRFSrZOGf~)5 lUZHvQrEbDwwBTGY}ezk5uZRR3E&qP-Fv zmgqe7wfBWjhb!o#@kX>Z+*ZEjyCiKqDd(@JT_5I RF-gBJ#DTR|?{HxhfYtHmzSV z`(s6=$5yH*rLYW2b6)pwo4dVk>+p=1`)ENEe@Y7ths=KY)BCd>P2uImcgp1kK7)gV zsSe#)(%@~PP~@b)n4aAt&CZ2qw^NPrCk7s`3E^He1TS-~oNEu>*C)4{Df}(2+#w7_ zE~hHVZ*G^EY2`zm&z^S=@fKW8D~nG2`iR=)JoOG6qXyup58kbOu1BL?hRMj 7VDua JV){c`&Lx)LwGG(%VW1QBCvvfnZ==mAN$sQG&<4> z+UF&p20Z*1qO^7Sa7CpihBWw7byp+VHO5T#GaLBqCxe-k36pxPhvkt{)z^&)940dn z`uCRtpXDnU68YNtuXrr9EPlS%>ejp2s$`60M^(GQF0Jaq4AJ&^2GuCdME?Dp`K}Fp zNY-i$!p%QO6ejlv=h{;unqs{7pZjFr<} _~TAs!wx3 zb*)RR@LpmfiS2itrbenA-(|NhbmAUS+$8R+A6a{2!QtnQQ<&inqrMEXb7sA~LEjR( zG4tANhF+oC+Z!GT>(e0Q%It1R!`vzAmgR75F~e08-GeHNt zV+yAAv&+YQZ}PGDuJZ?cRv41&R9DM;U9=WmGA*~zp_G|W`XEl^EHvhg7oo`&``c@D zclPhPpD&8At8m3JSa3Bk!nr75FYFCsCpszJiJ2MU?XUZfO&vTZ&moN;VFq%Ub&qMG zlT8eurZv;(`yr1nh**J5e0)yjox}+`Pj_vqByY8gKLY3%zcb#=5~`*5XXai0Ik*hZ z@gz>qM`yI)dUQIGndJq0rQYK4Hu^C1j3Qx|yp56iTJ_NRexjZ2=Cb6HPuOL{(6!3( z-tdh+dZ@jLF?e|!rXz^PWk>jUqwCwvK?pq$ 5{-pW-3=M$>#?%$#9s%(s8Yy?qoJOsaRLRh`fm(@iYi1 zq4Q1L?ln-Wju Q683E{ nc`IRMHJhPlf#Kc5i40_jemfwM4G2p(NHfW<6~ KKe15#~LU5lA=U+ zDpOT~6fu86ErB!D5x BA7rRI;>Z;*{ZH43c(~rNVDDH5Bs_6 zB-BdfNj;G97ctc2kdmFHspk48;*oB{gN^o*|JEjrUZjflLwN96nO;g)ciR?WsfNqt z1M=Q@p0@G&WDQ0q8nJUrU1qY$;V~OQm#I}&=MNXjuf06ZpTk8?`>ZYaIFt5lYLkE) z12~oTFp@3Fc+@B^U(oS<1m!4rSRA)^oKhe;Nuo!VXu~+VUCgZu(PBLDy$xJbnsj_D z4-nIw(fylnDG)%}Os74|`*e)WnU=97O|VCB#y~fYa&=D7 mD@l% zpb>8l>pv*v3ijX59+5`H34CaC=7%iT#sU6UgGxuhWiWEm1Dr??b;LrHw9NXAxi-~f z{SVcSBj+PgF8dd6RKQEPFG>jEsjT67$3PvAGVkr3Oz5<`abL+zn1`|8BKttaU=7xd z{dE*#LnhXn!zPZ? x<9kBe9sVdzKUS36uEWHUaxFA zC+&(DVrpPdwoBSBf*7`Z-A-CMeb`BOBo8qDNlt|Sx^K)MDC@Wi?c|DtImM7UDE;F5 z&<$XS27ZK#L>?;j>037BVT7RhDcHf_Tn>h?pp;kmRlKt8b)fP(c{I!K!%5dBZKm;U6~ZFqy7UW?17Dq z%|*^z?m$c#hrv@30ouPg2n7NM5fnzT!NfuI0nM`94;@AhQVd$946tdN&pTkLp-gjm zBxcsq{*V{U6;lHBf?Br23@dqGtkh%~urLC}yXqAj02SQM0^dLvAkInwFWxWVI6JYa zsCXs%H+V5z4`*67#2L ROl A1BZDm(gVrTPE zRpBdO?#O%*D?;Z)e|87yDJiklOP&bemB7^H+Tem@76~9bR(@srt#C!H4x$r|#2^mx zbe9$Im$N?(hEbksnI0}9Xc(3Y<6moCnaE6phnNtdvA7wy^hgJO_}L{ylVh2b2KS+d z0VR2G_!&LGMgQVQS)-I=0YL;~$m^p~cDkcj@F%i9>XxMWJ#YFwQNLh%22XPG31gQ0 zZxrz2hdK~Gu~1*6Zt>h 9zsIqX%*!fqS%v-q0p|sJvUX*CC1v1Dp>p@Z9AF?K0t6mq0_t)C zx${Jb>HaWf0!~UDf)KGV)^3%wlzd|9a-NhTKl)|UL4T}LA*!rP|F>Mh6zyAH#Jx?A zYBMNIbBMu0wBsA-LDpc&o-`mpFLrkeWZ;^b2 2ZZ66Q5g?>yW4Vv(pU=6-h}fbdL=gZcdc` q`svt36s>)OQCY0~uO)~)Z^sALWEl^=@M5qvk|9v= zxr4-OC4X(3CZJW$m@PGVs3euHiK6u)=b}T 8c(u26dbWKODo z!w|F|nNo}8m&4q8OD;5fr4fK|% 5R?!!>V~-Ox*vBnip5}6)^M`5`hPLGu+2l)zh>YxC!ckK% z*d0Pg+5zfeZTc@$CAHT-W;h1!zXz#F7bjJj wU`GIc! za(5y|Yq}4h+QB_4|0P=d nT0Rl>)PICE5dDk= zO0QkW3JIpWT_lxezc+|L+KVCV t;tgH*;V*Wueh#fs!Dq88&Va_xO;8 z$F+VulmCy%fk7OnQ>*bcYi@LhQSbQgN4s}mns*UWIz=)%B{K%`H%W0}sx+G}fG8w^ zp7{89!2qZgfgTCbac9`+9OE#VvekrP_jB$FT-cdg!<~;k+;b@Fy6S~Lvgrs$cg5 ~I)w%pc}bFLs9uf2P#rGf`8Qm6Qw*D6^|(r4?K!6s2mPOdW>S zIEI7B*(YQVlI~*H3Ap^`9X*ru!6~!^zPU+`;;J!i-e9HRv?n q2jGEga20EwMcSo^1nDc`Xs(80A zlo>cPpn=x+M12&HgOqGLKeiN7`V`;UL)!k}o6M?c-LJKDl)aY7==I@aKlvK7&5? z+bV@R;&MD>lOVI<{5*()X~+l?5i!M6t>4_{-Bw#r@EzpJP!8p!cX&+-T6qf2!CJ?O zv0>l_(cTT-(^OMaGcqc?CAIiMQYIE(mXQk{X<|er(J@Bl+z|LC-3+srL}ioAGYQ zcBy+GI`#Qz5)F{7rhL)Uu6T3lL&sm;R(X5>*ygpDY=!5cS<3x>ad(M_jD_du(tpMH zZII_}8Xixtc=7akGPet>74&gyjmW&AqdSnQMMd6TI{1MSuKqd-(b_Sw@5vcBnEne- zFSqIBy6-#5nN(U|+`O1B-K#vksAD+Bsa*x8pv&ft59VM~xBd>+me|zOyQ5l0FM)t5 zAJ-pZ|LU;yW@DJe#RK1vtz~d2bllx5Xl*sMr-x*h7(AYNZg;(71Mt>p*e@7?n 0C%|HnIoVTxxFN`}lSh`sC zc}diyF}f^3RspA3p_g+RjG{eU{N3E;<0oezEn521jh>&q>#^V?F9zw1i;0wjdcG-P z)1WfQ*VV0Y%llxkX^mCm;ChUeqMYu6wz}=()M581I}3HI$wrr}ZYP{E3enDYZ1s9# zGbHB$gxaHhRj(|XW`1oT0`s$O_h7G(B7`;!he>xEw;STJX43Os$?2puKjlG{wBv2b zZEC8o0x=6jwe0HnG`iuvTYtQTEYF#}rj;x_TEEO|q}S22j}rP`Y=}Lx=>4>;pievo zULB8>Wrv`vjf(>cUo0rrf?w--CufNIF_B)g-BQ07Z2T`nGqIjjpMXi #JJ{1~Go2(Ea}Op)0z^+%&|49Pqu@QPSjPwC@hD#!4K#+=@33 zKgpcFjv?Bn=r4k#^@YEi_|ItRVOI`Ag)L_Y4-Z3h<`PAp&xidjMC;XdiMvo3g7hcs zEW%b~lIGcI^Epc;`;u&Du(D0tAa@|$eKqrFFC4CLYW-;}3qLjGT&2fFDi}w7!7s#x zoQ%##<&E|Z?;JXHYNnJ|vk79<6>Hi6ADlh^7a`cW5XRtj6rId3&pzCC$wL2N?o6L! zvxS_MN6c4uKlDOne(GDF&y(F}`i|5ZWcTPQonLDC?vwG?6Un?p$Dk}&teIl@eog6| z4tq-AHbeNX1EXY;8|Q!5y5hLGf}iRKSZM-nhQm8}6uaEG$c*s=!FWx69Ev%YaJ5IM z%_2n>ss$2nAHZM*vtI;)IO2+N;(cib*h&_y1MRNynfCEyO6?V4|6mu7tLaQ>r1lWE zg$OvE0%hSoK|0r%CPUA9jgc7wkXc8JnDpEohLDJy&x*3o^J~J%8p%Gh2uVblkGDF4 z`j5S?Oin2*LvVl9k7vQj%9CByz6xs1;*Ph4&w7^wP {3(Z}yi?m=k z({$rsX64IO4`<3xWlJ$S9bZqMYX)j=^i|aSzb^}!(S4z|Zr%o?E-1+r0s|Y}jU1=! zn(8n)WP%5;XXs|Q<@H(TbhzN$y5-GrxP0`OdU$WGKD9eG>e^vSfK88Ukw3M+JVH;r zy9(b%>c+amdx1gWOAZO{)9s(wP76l{dk7Y=dWJ#>VO)2Jz}#=_;JSECE7(c@h%;T= z_-4BFt(>CD56{DU=QiFm0I}DlUGUlXh9#Qi=a>87DLhjS9*8(Xkq p)zNVmG*0`2qw=|6iukPB8 &R*aJc)akSKxzHlX_ z9U*O^VxOWt5ADudkoim0obr dked9d~27nZ#^Q zs*HY!pL2^2I~cv}c&*kFD q`5?#`ggJnYTDVp}8ezk{5H&_ tvSL0h#{KD3&d?!AtjmRpYk7py zupaM(99}WrD2=T+6kFr+_MTPo{GeDsly>z}usCFkqcbyl!lHL)2lm>*>%ukCY&9Nj zVv6h2Cr5oq4l~X8b02@F AhnTG{NL zqSHZBD&nHt$5h2{Q7Kb6 {`yC@R&7?fF_!GHwm-rwiHxw%6qY_9U)z zfoI&*zo+YSACQyK>o9cTX?}Hl6R;y*wO`7zknynQ(^Hd?Wi9U28txN# M)cH+--bh0Fed@)7>&1GeGbRIjR3QL@oNh`Y~Ha2_6`vi*&KM22@+q4e)( zG`rx)wI2^@5lf^n>t(g4F55b)Q$|3b!E2lSVT^m}-pJLK3xxN*!O$Z+y-bLE%fnCe zFL3al4g%a=)*rf)#wTr6u<0k{87${<)t48}s*j!3_4Rfs44Y-kE@gpH=WGxZjM}TU zi=zogvP^7b?vXCKIh};O%=>m}H+L%mZOegAVOb$hjvh|4a)Wf1b2y}7H1W$&?zg|F z)<+l*kFi-iCu^TO+)W$A#`hj?x5PUBZdKKTq~I_yYJ=xY%@bZ+@D#227S5@;%U}mb zu-nuPnaH{}=!Ot|#*KMV&rnNilbobKS7Ur&d)o~cg}g#J-@L#6k$_9(P@3QENj%Ql zl8Slf!^qaVPA19iavj>?WC(&kAcHuA1I2$1c7cw+OIXM$Yi;Ol%J xvl+$XV_@0P0LgL8z0iXj!n z=*}xzzP$+@IQ}i{U>2=hWf4P^JCUQOCocY>Q8N-2x^(R9SuakL1~-R;%~V9e51j3z z&E2cKJk1X=DRBuIN(ir3OBQrLF6(=8ehDIi2DtN?L=}Ug>`BPW2z6H>`+Dwy&Z3ea z&iy)NugIzUv}*(F8O2>2{K rA;xC`!d=7`>vBbj7o&mOf)8$p? z6zR`w!cp6Q5m1wmQ>JZQ!D`y{`;fLaumAoK7Cmjh ZS^^f$A7Lba=NLs_E)Ty(K)kR9DLKP zsN0VC4xMty{o-^w3H$kWGHS(cVl BL2eOn zi!cyUz4 >&^l}_qNdvxf`})H3cH`v(A=c(0P&c6w zo&4kV-D){y%QK9xH*_r5li8efDCnCK8CW1W7=izH&Bj0HmnXaxhoM7>gIss`47ab{ z(lKwYR9e~ =I(LqSyL<`ee|6@-a;IA9&iW`A7Q!dX z*9xQ)yt7;A96Dni<{w_y*W4mkxUCHI)|-9?CSHsY;&X^;`uzd&NX29-SNU&E9}BnM zkL!eo`=Mkxi&?o0D+3+Ac%~jKPhP&(cJY!ZWXyw)P|_q`VbY~f7bWEzZ^%f^QtCTt z3#D6otA7$^%k#V``(t7qdXDdo9GWygx?Q#C1hJ9bWppa$7=db9U!uLpc=X{~$X9 z^IN?^AiNF>3sXMVaKhQzpd&Ihi)!Bs+Q|T-WA-n95^d$i5N-X%9>;d_hG~sL+7_r1 zg0Hb*^65#y|KtUkOF|fcCX|LuYQop#^l0NWqsrAJW2aUgpBY;ip%kqc2>Puc@4Pnh zb5Vo3q$CluT*G5HbAts(oTiPuEMB+WZf!>X@KmEqv`&)@mdt|ec9wR;Y?OUl)#<*N zxh&6%>rwR8Mpx(UBaBb>WHKdP=DmAeItDTAec2$UCCpE=A0UXOi JfnZS3t6N z2dg#pc5dGwfP;A={^BM(EJ4QTcw;|;#GhDKFcE$?YLMo98*e;0r{H}(tJmt3z(8R1 zEA6Yl@X1=6)zwFKd1WIUb5M3++mjj+`005#Y)Hq;v-+|)ZCldRkWwBIbAp3NW;Dq} z_#J_wsQIaNv3w_XMBcE^Hy9N=L0zfui?Zs)t5t}u(#uk@EWJ*Xg;h*kOolfBfuT9n zrQVkC5MqA)w8h(Kmzu=-QhyjQW2H1Zcf5L}7D`c1vdA@rI#F7q0t8;StDt4^n8Z4< zRqVBx{AKy{5q@Kh8HBW|b|Fq?Tj7NGwB`TBeZJ}7pVBj_R(Xj|jk}dIsSFaUuRUfd z9h%t_pHV+%g1GzE6(7%xt3Yk)0b@GG9?AiKcr}{I J)4y z{;k@HUB2HOycfuj+2u;NW@5=6!MuU&-^4U$kmXHXWtOQBl6$j%tyU~e1`AaUS$lbK zvR-*)qdd}3K2+7vJT&hilrmnQ=4ysA?P5yQwJTpzT hnI&l88sCqid5=qSNto_I(!V57&Do(bjA8wqx3quu;K^5 zPV6Iy=fQit*_oJz`^?(8B+8L5JJeE|Tg@l?`aS1CU)K)BMVu<9GQ;Rb>NKej*>1B- zsTF0kjy_uMWgb%PBQJiar8GOeyFA3BrzGW$JuQ8ya)m)Iz#aok-4DmanL)V%Fv}ER zTI9Qh-D|{QV>cE?R;zvS3Vr^+uk^MrtI7$pXx!A(Uie+=+bjOCD(lz{8fAZD=l#1} zE&<`BxLA0CaVLL$-$gn=I>MfX{S#agQ5FPdmwHre2P|AvRFqDqD$0ULQaSs5OWPv_ z*16HWi`Qd61KjWm>dI2#;J6B1_q;WB@~tzK|3*SLwWMs>&GVCH?Pf) oRIT+f`2TN+Z`1UF)`6yr;_+{-Ea~$)TYG2ddg(I4tuN=SsPZ8Z(?RCD1kbYt@$DtQ zxm(TFA7`+Jg_{dd(UB?b9Qm8vwS(Isok;$+pW7yP9(`-9brCsid{sW$UER9c43V7y z4zPEJKuY`P<>$vGpi&hix!9HTL#`42H|9Qe@q3;rLlzMc9^WTADx|))SAb}k^o)%% z0)N6|nA p?@3j&R?7U>{l7XG%Z0Yr(J~&{3Y`s8% RUOCoPl;bF#9BFF3AE)>G_O}ypGE0u+7fzW zT- Pivq^(PnZ52;JU{`TiqArqunWi4h%-v@rKbPW>)aZ z$g}@y#(3}BEKEv3 Gf63g$Ek*N_e7h2_-b3Onc_zivJ?B% z9pa^Y|3ssgboAowGHca8J}#=L^T5O8Ft%V%E~nXmfMY%X5?5v9-cIv_mQ_q-v8Ung z#c4CZ)q`>B4PfG*UtS(gmu&V1qkah5u!(huBp{no!5k;q&~0MG+Uy&N-i-dDqNm|P zN*ag0sg#PhnO5YfN|@;WAu~ErNbE>XQlm+II=x-nE~23;!e(ZFmG{uur=3JLzLujc z^&Ov01&aw` fSdxl)4@tz@r#h~9m zyC$5;{s?VIJ4xfK_LYV$jpChrEN88Qt~i_F?DUo5mHf03ttpHS7?(R^PT^cMBERmW zm~+-FD8*xIq?zhRLt~de9lJ#{qs@ZbTqgE6_lDbF_HN>X40ZcGCXzh?Sslv_4g5WA zy_xLLAl$C194n70<(T3wr}|Ia!ooxQy6WOfvld3jb^H7K$H&Lx<5CF{a-c%ph{)4P zHs{X;vV9tK?&@ZrJ2T&Qy85_b{g?c)6I5SmM1W^x-z|M^WP}x%w0CMLzFsJg)Tn6M zUa`KcJ~tMQbo+6fRu|4}PEW&1rWOO4uGsk7F=V~s#Hg@n{_8D_&i~MKl~HjtO&3{U zad&qJP6!UcArRc%H3awI?(P=cf)m_5xCaRC1b3Hj$oqW1_RKjuGd(R;)wgcnQZw^l zh1qT6_?_P86lGmTjyf_d*)Z*<>9 XWTZ1jx8GA2 r#$$}e& z*_@78z(~C(R!&-r9*l~}xVBJ@w+~EN{8K>3$Fk?<+Lv_6zW%iLxf88Whf|^Nck#wY zMr?AndU|>|zE++`tj?0m&o`NC`y3Ud{a&+Fn?v{5SppUi6UExEk? S7q;l;NMjO-beI11;tlBA#cEd@+e5;MR5OWZfzZ@QjrRaLMt8h-W>e#es}cK z(avW7_{wGOI%*Q!39^urdH~2*!$G#a02C4TL6jloh4G{0abWSq!go!{KR4(SmU9~o z7#?-WG5*sdb39i42j}Vv&TQWfpV}!o1-P7zzR@PXhJ1@(7@VWBS)1L`&3$m8?3 )$ZpR- yT4*o87ho{V!R;mq`eSW$c z4YTPM<-3zpd%1?ze{Ukv5Xw8U^*f^2z9KS4AB#%V{OTJ?3opCKn{j<{;0QUd$u9Vr z^+33jFSIT(S%4jWu>@FzCNI(G&o5^m~3%re0lL0rrH z!1sJzY5+Jc^eA#RK>1HVyFl&w!`C5LOeT>WNU+^Ktaj)HMO4TztO6wq0}+43H_f;Q zF-13M(sQ8X&kp+EN~|g37bz|$ia%6mh52+1U7|V4LBI7i2U8@8-EDN29W~kr_^%2{ zXnPv 8{QAXG2bySenc>BCpl$tyZvnyJMy!YwoR{ErfuX&a?Gti zWk*ju+p2fWCd=xPPQma&XI=*4%Z?wi5+6p}AHhWB;!gkH-tCfO{sF&}42ov_YucYt zkM`Y =v^7h@>w}U%>+(zAm;NP)#$W)eBjKT{4G5a zAcv(*2Ia OXyO;+c2P?q2tFG&a%W+9LT}ZibG=0~D{~Xd!`i^VoAY&c z+2{Nv{Mo}{Ygr?Tfu7z^^vpf?k|d>bcT&2Ys7Q87$=;1zp-ij(JdUS&Y1kntKf_Ts zNfjq~&Bdv5#G u{rXi%I%z$T6R4)H!X z0U8`@yC5KVIy4FAh|AafWdbQ}$?l@IhoFB1;bCiaw#z ?sESW7N>>oMm~8&Wx2DhwswMKPP#!Pt=kPh?s3pEIAc1_ z+;Kg%*Gyy*P2dgkfpLztRvnAX&)1_B_IC~9MbPGNuGQE$-W=zXYmt7oI6nv_BcBvO z?~=)V)@y2MU1e0#kQjp3Q~RkCY6-!vkJ2>~jv|mxr6Hgs)0=R&L?Ab8MaA(Hvu;ZL z7oGDe;!&IQGfzvyU?S1j%S7;0hbGmno%0qkt#18eT*5rD`K&&DL%A;q7E<8xrlppl z_+`|oaS@$v*}KMP?FESAS$nJg#F_2I;*o*M;UJmU?2cy|Z3Tz8Mw~wzyJ 4 mJMB7vm0?#D1 zdtA3DDj3GiP$^*-iM^W`3wz2>CT3Bln@woEI12qW^Wn4WS|xXy>oEn&96p%9cw=Cf zOQ_PYvFd2_{E$zmV!4m>Mf#8*68T4 Si|q&Ctcjr zeU?#GY0`7&A+BC&6zY3SvM?F6{+p!L=LelnRt=`jOJ)z{tVP9Nj2-xF?;d17;(2ev z7;lgt+qHE6dK$1ZcFFFkz PO8{9&qKnyf!98}w>p#Z4p|7M)xO!#^c1k86d0{dr+<|H|iP zCudTwynVtYKOzpTs~U9w*RewcfoLR)k8XjnDaqaAc5`N#CLAjS{@ClZC|mD|$-%~( zz5er0NT|!z!TwsfkKBrxm2B%Y4f_wStwAoqReUeXaRzdaGhdCc ^Hq*cGYtFO_>-cFA{_4D>;3r1DIt)1o=8B}tJ(X~EY~A*1CrQKa zQ@1wXH`)v(hjH&et2+I1eIA z9%Ga!=8AZ zykxx}XTG Fn(M;opATSAI_h&WXnoX_x)=Ta)G) zb`ir`HrK&W_Nws9R!4|^6~hkg#CH?HTW^7ZR$IQcPI>&D3AwND3^&nvt`}6pzkIfE z1z(UhFBdEML9P|n(LG)UjvKciKU}1pe8||IZTzzLseGp0tF682yOx9f{^0ZJF=PyG;*6E9p~cyU7f1U!IT2#_&H(W z6=V?o!6{JR148ZYgQd=zK8;bYS;NdrSPqV1^at6>%cG=^&Y`8)0$tJW|IT?kLs2>! zcUMISSIoY@+d)H^ktaPympN)W@gWR{t#j%CbFo&qBQlF6#1NBHgSC?yB&nXdTjp+} zWcAKk(Id)c@Pj@>njQNiC+2X=d2MvIoxQ?LL+yS)q~4$^zozVvvj$hPw<`H~VtA4? zuB Z?4YXWJI7Pb3&`V@Gq6j`5NVsTDO);pAwLi0^ zT;JPg5_NUhzwq?z5b~l^pd28p6H8GIRVC;> 3*4Ng0} zVf?7e8XB3?7S2TO#UJRWMXsMIdSsSuCxi4(P`5Nt(Q=5cZ~&)MD-FK4rYFP7*;&+F zR!&ypsT)OxHtO-5u$bljD++r=*284w;L}}wLXf#S>30HtRn}E%IrY4{Gthdtw^*O& zv`Rc$H4jMaT#adsjDmc#$ duHQ6VQchyqL5f+!ShJ?+TCxi;8sj+$;NmI@`0>Lh+2$IwO=p^PqZm~L(Zh1)Dg zxURGWF2+g>!7ZdzO_(lm|IY>B#@4xa?1G`YTBfWceKEN&?zp}F%2gto(2cTl^dW-! zT9 zk2-L(haCJZkw!CQHG!zCh<1+JX}a>+U%*+{x261V8j=jA`_r*sZ)L zGs-{84b&@~qjYL-dmE`3Cd)sOSGizPr03-7WW9E%^I6(( z_Oq-?u)s}pwL(v^Jdv-HQoDVdvd0@B&*94O$1V#%vmghrM|FMka|K0%n>>59d-X|m zND 2@4M>Lk(Q!obU<4 I@LoB;9xm_t sAWAVWzse2a|S95qsMC(z&b4ItO!hA1=4_^Fw-|n dWVJcG?}aJTVWO|H#(%CO!$IxU9Wy1-vK4<8`8Y@b_`g`2t{w($O&+XG9C+ zg0m(fIo@wLkRDMew_;nf(9lK@LbI)!{Jc$A_gY-`57ME5ChbHIYRiM$+cn3vUvZSq z+k_IfIvu%i hVqfXxR`JeEgt&Z q)Ki)jW0z;Z#Y^C+j6qvnGNChxz$i*=#nWKCl!gXrCCwymp6W`g~Dw&3D>n z%&(*)-;>2WOG8tOF1(J8CS0KZ-CH~b(e-Hy7q#=|7*>1WefIg$qPE-|vZ Q4X8((8G`7cSS+ji0FfZWd!h?uSJOcdy5Ch-;V+3;aGlKFo_`n`pqQQy`R _k&Dxy?$UK-sqmNx4Ry4PQ#*=(up(rcFpzr9H&-y z*Gb*%FG~WXo#96k^-RbV4k8jLz^7Xyy-L&wt%&)*nP{qh8gZ(jfu&(p-P_8Aj#Z|e zA1f)Z+ @Q6Z^G2T) z94v~dsHdJ|Gp6BCd ~Z$D z!d$&buKAn8WFHv|3rp!EdR&J+YhFn37AmB=11CKALpWMB78LIVvQd-_r+2@u*x9=c z>;O-O@psG5zfZ9j=LKLJY`2*3 #=Mc6LIy3WUAAU#7MO*(c0e zoa_%@3|?I*`P@;D_qP`Z7G-Dz 1>k&d~Xg6t6sbekE@m{D;Ww%9iW_R;%hj#bE zp^`*;{p`VVUTOerDM2&?4?hU(iKqT*E_X~oAB0w|4FX0pl6o9NsOKD08O;>!i%!Re z1tbMO77h*xpZ(F*cl@usO-|n(L*`55^m=(W0#+9@wliwv(T>!GI#w9l{8p&@A76*> z@8xmL7psLuYkDC9IKf 0g39TRN99L zAsfQLLG(aE5Di!PdZ+Agf3b6PbkuXGE+Z}d4x1~ 90mW zc5NM+SOlpD88RF>K5B$Z#~v|kK|X|yXx Hrp{c2 AI_MC5ld#oId9KX_ zqHB~rq) !#On#T+8OXp`bXK;lWf_bYRe8?R69T}EiDg00(%U4O 7~vMnZNhb!GH|ScPWlGIO1CO; -&k`cIN{kE~<|r1m=esC|+N zfgo8^`4)Xsgf-0&mo8J`n6!ZXC#O8YY~&*-LC`p4s?b^hKv*dZIFan)ie??57X*1y zg?tgH=Xhqa-n4j-zWxp7NB4bSNu(i!V2$qk4$21wEzXIM1Zws6i3bgSa>}-SUx|WT zffOp J93+nLYn}z%Fprh4-`Vq@{VM#4FTUs zGRP5A+)ACMjbZ3SA`{{mXcw@k_l{}Q#{6e$xapDrb%>)bx|ckUaW*A1$&`Ti$FvaA z(T6-(Vj%Uu@Uaw`W{$cW`6bO|$pWq6w5%mpQgd zmeRdIE)n?#sqv{C(y(BiCB^NDIVF(HsLk`e{tzVD3z1zBkDe4{PNrfBS2c`DT+bs3 zdgSJL4Rlg4SlxQMsY4TOz7*?AHZT3yh5EEziLOVz?>irqoB=eqTT1^Bh{isSYb@$; zO7l89xg-oI&HAPe6Urg&f8f$LBBE+S$Q|Hf9fUJhBn8`Y#SC{x1o(t*)oRp%BKn zEP7&?)s7YJk0lMB(CR`-BV5%88%4xTcD+ekwq>4QV&k{k$DOg?!NToZiZzY)V-uu) z;a-o>ehPmI&1Yn>P?fG+Z2kVxQwRh7uj0DyNY%b2L_`-KNeomr5~$z|d `n6Nqx44t|E5`ERS!d_wG(m#m^iO}nDQK;gy0ky zLNXw>YO)Ie1!!!kGp{u@ZCxO{L$u;wROCuWU%q2Q2GIDyOvNjKrapZq{%i;kKN~Q1 z!xwN;eEx3lVKe!^4E%AQgFr*~PV$Ax2H! Mjje)=e9@}$L3dw* zcFFvGrwF(4^d#C`V{P5=&(-5?f5F g zKq5Kp@4!gpR!EfOGSaY8=fx_}G^uTL?;Up`BA>Ame}GpRDD(_I ?(T-bt-+MVJ8;NAEeYMT2YOD@x(8ZH} z^#~n>tWqh^mFML^EImv0Z7487XE%R;alNEOaQpg#p<+1rXaMOTXgHKWdUiX9>jPEm z@?I>425F6eoP@q~7mz(@WSDCtX4~raN5P)k;3aL2OM{tww+`!Wc}7;$AEdMBy}$g? zUyiL4-`1>b48%|)tkLSiMFl-@W(!=dFt-u$`I}Bv$}x=`mFe$3UuEY&UvV_Ddo!d+ zS<1C^*&%#rVaz?qO|?4 TwI0XSgJ3juHCjDVo$$vD=s!uxj_2wZu<{&%l64y2L;=TiMF>wk}$Vax`E zj38Ym3}y)SiVV4C2G%dn&ox_|N~1m?guJd(0jf;iKuy$xKlMMN>Z8*|ffu~Z6})fk zNYSf4K;cY)t_D jvCI<9H>&`v7Z}q(tf*I#FM{jLTvjHJ1HdvI7B#uh{Ko)a2=k1rfW$9?<0b2 zRdtZ482Y+Uy^;OxBu&tZ*Rm=3v8SoI+3RwQ%hJ-)=lNQF KY{Vo8~}Z6 zznJfXB;Q7 bap7Fe9+lA`+EQbUEa zgS-y<+g)#Ca7|{QF*K*F0aR=@=WNJl{F5`eEu;T_$?!!2hCydzy?WCkj7IaciZ_PB zF)Bdxted^v{fZ`;XvOiTSmAB*P?)KtIuAGFOj-|LlM$VkVXB&8Jj$L&DSnYLT?k59 z5v5rPREzw-uVtc`6rwKvL%>E3*_6qY@MB7`!1faufryNOk91Ju`wjE8U(pcdAqTUd z_r1dH!-dtFa@M2ac3?5f7upYG* QLy<|jBqN3rItgaK{l?uj30|G?i zY1N{jxOdO +@`Aj_Rv)`di5SH z+Lmk9h%s_~q?hzdY(^EF(9qidLO6ouPMAD~YsbqE^lqfzX;wo}Fb<3>7QF`f{-y{2r%)y0MIm4a|ij zQEXNq5k!HLTv#q0g(F>4otn7qRsbVbM2Dz^LqW~K&XaE-gU22Ed2CoZ5(k0m%N*?l zgt{=jQ8+&(!TGF`z-(EfW)5V}R9NYdy@8lPWFy%0%e J$sl=$db*#{3 z6&x@|JP5o62p$L?6cp--yO4^db8`{yJ(!ODSf(Ok8lDo6R2{L!-1sdNg4*<0$f57h z9I=W;&_%?PMAU1mLBc+2^yJUt>HZGL@{GRTP;kQN@XduyEb=m+n9wf6KxMU{n bRJRY27}mk{ezNvh}vGxo0VN4f-2ZPI8u6Mui;R| NPShS6D85pSM)|%XXI%N+e%)kbEfQUFIys|gwx3qhL-{5LdB+C|y%J_EWjZnr z!HO1M3o*l3+-y2E+5yV=ToWs0hV>TVvE(j{GR#?~;e#O`HWX>x0yi|3bXK86e?6;< zayO(Y_C$x=@^orF5fZpyDl7g9Zc5(IL~Ra?{-BDgfHDF$_oQ_Bnw(TxL3s-~ya7ie zG$&5jq643F(r4nbW|>aFdKn~uh4L0mT9G)1M?W+RkbWd4M9a=hPEJoxPfkWEw7WTQ zE~g=mkwMJjUZ^=+9*kUB8I)1dQXem<&Z*HA{|*=KsI6Z9Ny*}3yNJ3br>jzxYn&Y? zsynq!g_&hcYBfIfMxyiSeGQ|5o2|WmNUD#MepT(rVBehJU~T3o3aXD9HOsh^Y~()i zqr$#NMSpSa<@G&__Q=)!!4Ob!V-QWe(R0d_D%0h@}1ass*;ssW4H0t9WZOnc8G* zy>DxkaJCnt8yOsN%@EBUPu#) 7tXEK_q+!_b4DW~879BvjKU|Q*;rN-5TEKfdc*tmw zsK#;@zW?T%0)3y!45H(evzE9w)-0#kHnyIhB_r`RPCt5!a4+4DoU@DHBy(`Oiw(wK zO0t^$Jyb@{HxGIFWzQ|2`;Pz4q4RGQF89!!JC-CSCe#V>*exx|SlcF@ }Wj z+jLivfN-RzXZP;0#l%MU!?SUNT`0?pIIw2Yy7v0I^CU1YKa(!b&E+%Lt$tTlOHR0Q z>U4+l&}vs$A;qHn=S}3$Sh;`y_|Qr%SIZQ+H=@+m)YM49E587TPH}V^ieQxcfn8 (S6~%;Mp4scVyBa3ia8IiZzvi4E+-n{RFifhY(+{xF=1gYQxg{V~tB^SMC_gKJ+> zQAuOKL{IO;*~3aa+9)Z%F(svZoDm9+wP%wKv$kXy!7;*?yV>LMK_zCBgTG7~K_<18 zT+8SrzDFb}zcnVsF1*_SEj97Iil(}at`+sSU=R7!6s4yLHr_4nns?~fOq}8krYCwQ z>>O2}cQ*At;`})(bKo2xAtB~%EQXLBXD`<4hhJnczn&fUZ`$Ei31NNPxI-R_Llj5m zV3enHN^F(unHp_qnd&(oz&OkP%5|jEW )e-}a43npSo@kdn|FE&&$je7<)^MAaz%zrX zwA0DRt~R7y*)8@jhJyrH^7JNEsvnvx)8eAiS}i_fs{LJc993rdU>YR5z*+Xc2zdrQ zCoa=BEf49?B8b}b-3+9)0=(fAGJ|b+QDvj>XJx~Gu3QTRib-RLx_yJyslPj2VXtdo z2LZ2?18e+i<|$g69Jji9e23AC0xs$)psnKZjeE@7*f=-0*5fo|11E>kD=T5}2hUC^ zIkUWZeEJL`1NHx6NLG+mWjsTl;=Vg3+?++nu(OuVa-yK~iFh3Q_XkQ&0~cSuCrDWY zw=98(-gyUid+E;_Jr^O~((}B^%-F10Y>P}nL)o#u#ap#`4=u w5SMlBcpwn=}B9g@Ym)(u-|1o;>j46snW z0@$L)By8@!i}&@`dV>g1zeN^WZn7QZgl==-Rrht9dxMEhjkm2NAwOJ1z*5;S^U+XK zL&A00J8Atqi<~*+b|uEZPl!#AV_I;>5luF@OAQ+Ib0Lbhhl5WpLd@%%naf32)aLB< zN032lXU3xP|DLmL6s7Hp W+#CrR0Z9ucm!{29&dO{tJhF z2&a{HC^yh(yf6q*d>qeL#*7U!u8PlCkpY2ycD?t7Q;>{UF5kr?M&p)iJJ^w71vYC9 zPN2))DSfs6h#eeicq(eAM2WXDpU^4B8eM*4ra=85kJdKbH7czo;$#t9(s2gv+K_W# zK4R}J2v?}WQ)(*2wpsbU#D$)PDuxi82D5^Lk-y6-*!uabppG^BaM*u)fATDFEmm~C z-rqt)a|9>MfJGvI-n}r& -viC200EOgmhqOK4NNw>Z`l3vvG3R;CzHDGD*F o{%gXEg{pWs3|AE|3{3B)` z>gPn9EYn=dmL47H+-0BNdDow46RR&Wp^%eqo ! zMI7VrUYE*Me0KLx{$n3vK3Ed$l;1>#JMN>)#caL%Cz&bPp*8B2N}BJQM1KYI1=e3e z*Ul)~<_t_Umm7nZTI`Px$-hfdbwd8oTxJq_qyS2f32!#w-aYEo9IO}C{;9-%+7_pe zymy{EidHo3_Zi