From 6137a917e5d2500e6d36895b04c7abc3d9acf78d Mon Sep 17 00:00:00 2001 From: Kevin Hufnagle Date: Thu, 29 Jun 2017 14:32:10 -0700 Subject: [PATCH] Clarified conditions that require client-side unbindService() call. The documentation for android.app.Service includes an example from LocalServiceActivities.java. This example now better shows and explains the distinction between binding and connecting. It also shows the set of conditions that require the client to call unbindService(). Test: make ds-docs -j16 Bug: 63118511 Change-Id: I1276de3f9421e13e1964039d37db9adc87f3039f --- .../apis/app/LocalServiceActivities.java | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java index 536bd8117..82597150a 100644 --- a/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java +++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java @@ -23,6 +23,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.util.Log; import android.os.Bundle; import android.os.IBinder; import android.view.View; @@ -36,7 +37,7 @@ public class LocalServiceActivities { * This demonstrates the implementation of a service that runs in the same * process as the rest of the application, which is explicitly started and stopped * as desired.

- * + * *

Note that this is implemented as an inner class only keep the sample * all together; typically this code would appear in some separate class. */ @@ -84,15 +85,20 @@ public class LocalServiceActivities { * Example of binding and unbinding to the local service. * This demonstrates the implementation of a service which the client will * bind to, receiving an object through which it can communicate with the service. - * + * * Note that this is implemented as an inner class only keep the sample * all together; typically this code would appear in some separate class. */ public static class Binding extends Activity { - private boolean mIsBound; +// BEGIN_INCLUDE(bind) + // Don't attempt to unbind from the service unless the client has received some + // information about the service's state. + private boolean mShouldUnbind; + // To invoke the bound service, first make sure that this value + // is not null. private LocalService mBoundService; - + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been @@ -101,7 +107,7 @@ public class LocalServiceActivities { // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = ((LocalService.LocalBinder)service).getService(); - + // Tell the user about this for our demo. Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); @@ -117,25 +123,30 @@ public class LocalServiceActivities { Toast.LENGTH_SHORT).show(); } }; - + void doBindService() { - // Establish a connection with the service. We use an explicit - // class name because we want a specific service implementation that - // we know will be running in our own process (and thus won't be - // supporting component replacement by other applications). - bindService(new Intent(Binding.this, - LocalService.class), mConnection, Context.BIND_AUTO_CREATE); - mIsBound = true; - } - - void doUnbindService() { - if (mIsBound) { - // Detach our existing connection. - unbindService(mConnection); - mIsBound = false; + // Attempts to establish a connection with the service. We use an + // explicit class name because we want a specific service + // implementation that we know will be running in our own process + // (and thus won't be supporting component replacement by other + // applications). + if (bindService(new Intent(Binding.this, LocalService.class), + mConnection, Context.BIND_AUTO_CREATE)) { + mShouldUnbind = true; + } else { + Log.e("MY_APP_TAG", "Error: The requested service doesn't " + + "exist, or this client isn't allowed access to it."); } } - + + void doUnbindService() { + if (mShouldUnbind) { + // Release information about the service's state. + unbindService(mConnection); + mShouldUnbind = false; + } + } + @Override protected void onDestroy() { super.onDestroy(); @@ -154,7 +165,7 @@ public class LocalServiceActivities { doUnbindService(); } }; - + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);