Problem
In my Activity, my bound Service leaks. But this only happens after the first screen orientation change. On the second (and following) changes of the screen orientation, the service does not leak. I can't unbind the service in onPause
because the Service needs to run in foreground (if you unbind the service, foreground is stopped). Also, after rotation, the service still works (I can still call methods of the service).
Environment
I am developing for midSdkVersion=8
and targetSdkVersion=18
and I am using the SupportActionBar
.
Question
Is there a way to prevent the Service to leak? I didn't find anything that helps, yet. Am I missing something?
Code
Relevant parts of MainActivity that extends ActionBarActivity
from support library:
AbstractPlayerService mService;
private boolean mBound;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_layout);
// Abstract Class that extends Service
AbstractPlayerService service = (AbstractPlayerService) getLastCustomNonConfigurationInstance();
if(service != null) {
this.mService = service;
mBound = true;
}else{
// init..
}
@Override
protected void onStart(){
super.onStart();
if(!mBound){
// following line is line 170
bindService(new Intent(getApplicationContext(), PlayerService.class), mConnection, Context.BIND_AUTO_CREATE);
}
}
public ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
mService = null;
}
};
@Override
public Object onRetainCustomNonConfigurationInstance () {
return mService;
}
LogCat
11-27 15:42:31.992: E/ActivityThread(25111): Activity de.malaka.player.MainActivity has leaked ServiceConnection de.malaka.player.MainActivity$1@4053fc20 that was originally bound here
11-27 15:42:31.992: E/ActivityThread(25111): android.app.ServiceConnectionLeaked: Activity de.malaka.player.MainActivity has leaked ServiceConnection de.malaka.player.MainActivity$1@4053fc20 that was originally bound here
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:938)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:833)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ContextImpl.bindService(ContextImpl.java:932)
11-27 15:42:31.992: E/ActivityThread(25111): at android.content.ContextWrapper.bindService(ContextWrapper.java:347)
11-27 15:42:31.992: E/ActivityThread(25111): at de.malaka.player.MainActivity.onStart(MainActivity.java:170)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.Activity.performStart(Activity.java:3817)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1624)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
11-27 15:42:31.992: E/ActivityThread(25111): at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 15:42:31.992: E/ActivityThread(25111): at android.os.Looper.loop(Looper.java:130)
11-27 15:42:31.992: E/ActivityThread(25111): at android.app.ActivityThread.main(ActivityThread.java:3691)
11-27 15:42:31.992: E/ActivityThread(25111): at java.lang.reflect.Method.invokeNative(Native Method)
11-27 15:42:31.992: E/ActivityThread(25111): at java.lang.reflect.Method.invoke(Method.java:507)
11-27 15:42:31.992: E/ActivityThread(25111): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
11-27 15:42:31.992: E/ActivityThread(25111): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
11-27 15:42:31.992: E/ActivityThread(25111): at dalvik.system.NativeStart.main(Native Method)
If you take a look at onRetainCustomNonConfigurationInstance
in FragmentActivity
source code you'll see that is calls Activity#onRetainNonConfigurationInstance
and that method is deprecated since level 13. In your case you can very well remove that method since you're anyway binding in onStart
... and you MUST unbind in onStop
:
@Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
}
According to Service foreground documentation , there is no direct connection between running a service in the foreground and having it as bounded or not.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.