Activity <App Name> has leaked ServiceConnection <ServiceConnection Name>@438030a8 that was originally bound here

android, serviceconnection

Solution

You haven't provided any of your code from `LightFactoryRemote`, so this is only a presumption, but it looks like the kind of problem you'd be seeing if you were using the `bindService` method on it's own.

To ensure a service is kept running, even after the activity that started it has had its `onDestroy` method called, you should first use `startService`.

The android docs for startService state:

Using startService() overrides the default service lifetime that is managed by bindService(Intent, ServiceConnection, int): it requires the service to remain running until stopService(Intent) is called, regardless of whether any clients are connected to it.

Whereas for bindService:

The service will be considered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed.

So what's happened is the activity that bound (and therefore started) the service, has been stopped and thus the system thinks the service is no longer required and causes that error (and then probably stops the service).

Example

In this example the service should be kept running regardless of whether the calling activity is running.

ComponentName myService = startService(new Intent(this, myClass.class));
bindService(new Intent(this, myClass.class), myServiceConn, BIND_AUTO_CREATE);

The first line starts the service, and the second binds it to the activity.

Problem

I'm working on my first Android app. I've got three activities in my app, and the user switches back and forth pretty frequently. I've also got a remote service, which handles a telnet connection. The apps need to bind to this service in order to send/receive telnet messages. Edit Thank you BDLS for your informative answer. I have re-written my code in light of your clarification on the difference between using `bindService()` as a stand-alone function or after `startService()`, and I now only get the leak error message intermittently when using the back button to cycle between activities. My connection activity has the following `onCreate()` and `onDestroy()`: ``` /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* * Initialize the ServiceConnection. Note that this is the only place startService() is run. * It is also the only time bindService is run without dependency on connectStatus. */ conn = new TelnetServiceConnection(); //start the service which handles telnet Intent i = new Intent(); i.setClassName( "com.wingedvictorydesign.LightfactoryRemote", "com.wingedvictorydesign.LightfactoryRemote.TelnetService" ); startService(i); //bind to the service bindService(i, conn, 0); setContentView(R.layout.connect); setupConnectUI(); }//end OnCreate() @Override protected void onDestroy() { super.onDestroy(); //unbind the service and null it out if (conn != null) { unbindService(conn); conn = null; } if(connectStatus == 0) { //stop the service Intent i = new Intent(); i.setClassName( "com.wingedvictorydesign.LightfactoryRemote", "com.wingedvictorydesign.LightfactoryRemote.TelnetService" ); stopService(i); Log.d("LightfactoryRemote", "Connect onDestroy() attempted to stop service"); } Log.d("LightfactoryRemote", "Connect onDestroy()"); }//end onDestroy() ``` So the service is started when the activity is started, and stopped when the activity is destroyed if no successful telnet connection was made (`connectStatus == 0`). The other activities bind to the service only if a successful connection was made (`connectStatus == 1`, saved to a shared preferences). Here is their `onResume()` and `onDestroy()`: ``` @Override protected void onResume() { super.onResume(); //retrieve the shared preferences file, and grab the connectionStatus out of it. SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_WORLD_WRITEABLE); connectStatus = settings.getInt("connectStatus", 0); Log.d("LightfactoryRemote", "Focus onResume with " + connectStatus); //if a telnet connection is active, start the service and bind to it if (connectStatus == 1) { conn = new TelnetServiceConnection(); Intent i = new Intent(); i.setClassName("com.wingedvictorydesign.LightfactoryRemote", "com.wingedvictorydesign.LightfactoryRemote.TelnetService"); bindService(i, conn, 0); //TODO write restore texview code }//end if }//end onResume @Override protected void onDestroy() { super.onDestroy(); //unbind the service and null it out. if (conn != null) { Log.d("LightfactoryRemote", "Focus onDestroy() attempted to unbind service"); unbindService(conn); conn = null; } Log.d("LightfactoryRemote", "Focus onDestroy()"); }//end onDestroy() ``` So the binding happens in `onResume()` so that it will pick up the changed state from the connection activity, and in the `onDestroy()` function it is unbound, if necessary. End Edit But I still get the memory leak error message "Activity has leaked ServiceConnection @438030a8 that was originally bound here" intermittently when switching activities. What am I doing wrong? Full error message follows (from the revised code): ``` 01-02 22:04:26.642: DEBUG/LightfactoryRemote(2024): Focus onStop() 01-02 22:04:26.642: DEBUG/LightfactoryRemote(2024): Focus onDestroy() attempted to unbind service 01-02 22:04:26.642: DEBUG/LightfactoryRemote(2024): Focus onDestroy() 01-02 22:04:26.672: ERROR/ActivityThread(2024): Activity com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote$TelnetServiceConnection@439e51e8 that was originally bound here 01-02 22:04:26.672: ERROR/ActivityThread(2024): android.app.ServiceConnectionLeaked: Activity com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote$TelnetServiceConnection@439e51e8 that was originally bound here 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:927) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:822) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ApplicationContext.bindService(ApplicationContext.java:842) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.content.ContextWrapper.bindService(ContextWrapper.java:319) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote.onResume(LightfactoryRemote.java:102) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1225) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.Activity.performResume(Activity.java:3559) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2838) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2866) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2420) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread.access$2100(ActivityThread.java:116) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.os.Handler.dispatchMessage(Handler.java:99) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.os.Looper.loop(Looper.java:123) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at android.app.ActivityThread.main(ActivityThread.java:4203) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at java.lang.reflect.Method.invokeNative(Native Method) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at java.lang.reflect.Method.invoke(Method.java:521) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 01-02 22:04:26.672: ERROR/ActivityThread(2024): at dalvik.system.NativeStart.main(Native Method) 01-02 22:04:26.692: WARN/ActivityManager(558): Unbind failed: could not find connection for android.os.BinderProxy@43c509a8 ``` Edit the 2nd Thanks once again bdls for your suggestions. I did as you suggested and added an `onUnBind()` override to the service. `onUnBind()` is actually only triggered when all clients disconnect from the service, but when I hit the home button, it executed, then the error message popped up! This makes no sense to me, as all the clients have been unbound from the service, so how could the one destroyed leak a serviceConnection? Check it out: ``` 01-03 19:38:30.837: DEBUG/LightfactoryRemote(1118): Focus onPause()1 01-03 19:38:31.577: WARN/IInputConnectionWrapper(1118): showStatusIcon on inactive InputConnection 01-03 19:38:31.587: DEBUG/LightfactoryRemote(1118): Focus onStop() 01-03 19:38:31.600: DEBUG/LightfactoryRemote(1118): Focus onDestroy() attempted to unbind service 01-03 19:38:31.607: DEBUG/LightfactoryRemote(1118): Focus onDestroy() 01-03 19:38:31.677: DEBUG/LightfactoryRemote(1125): TelnetService onUnBind() 01-03 19:38:31.727: ERROR/ActivityThread(1118): Activity com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote$TelnetServiceConnection@435baeb0 that was originally bound here 01-03 19:38:31.727: ERROR/ActivityThread(1118): android.app.ServiceConnectionLeaked: Activity com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote has leaked ServiceConnection com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote$TelnetServiceConnection@435baeb0 that was originally bound here 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:886) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:781) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ApplicationContext.bindService(ApplicationContext.java:820) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.content.ContextWrapper.bindService(ContextWrapper.java:307) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at com.wingedvictorydesign.LightfactoryRemote.LightfactoryRemote.onResume(LightfactoryRemote.java:102) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1225) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.Activity.performResume(Activity.java:3530) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2619) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2647) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2287) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread.access$1800(ActivityThread.java:112) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.os.Handler.dispatchMessage(Handler.java:99) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.os.Looper.loop(Looper.java:123) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at android.app.ActivityThread.main(ActivityThread.java:3948) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at java.lang.reflect.Method.invokeNative(Native Method) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at java.lang.reflect.Method.invoke(Method.java:521) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540) 01-03 19:38:31.727: ERROR/ActivityThread(1118): at dalvik.system.NativeStart.main(Native Method) 01-03 19:38:31.777: WARN/ActivityManager(564): Unbind failed: could not find connection for android.os.BinderProxy@4370f8a8 ``` I thought it might be something like you said, where the binding to the service is not complete when `unbindService()` is called, however I tried calling a method on the service as I backed through each activity to verify that the binding is complete, and they all went through fine. In general, this behavior doesn't seem related to how long I stay in each activity. Once the first activity leaks its serviceConnection, however, they all do as I back through them after that. One other thing, if I turn on "Immediately destroy activities" in Dev Tools, it prevents this error. Any ideas?

Original source