问题
在我的Activity中,我的绑定服务泄漏。但这只发生在第一次屏幕方向改变之后。在屏幕方向的第二次(和以下)更改中,服务不会泄漏。我无法解除onPause
中的服务绑定,因为服务需要在前台运行(如果解除绑定服务,前台停止)。此外,在轮换后,服务仍然有效(我仍然可以调用服务的方法)。
环境
我正在为midSdkVersion=8
和targetSdkVersion=18
开发,我正在使用SupportActionBar
。
问题
有没有办法阻止服务泄漏?我找不到任何有用的东西了。我错过了什么吗?
代码
从支持库扩展ActionBarActivity
的MainActivity的相关部分:
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)
答案 0 :(得分:2)
如果您查看FragmentActivity
source code中的onRetainCustomNonConfigurationInstance
,您会看到调用Activity#onRetainNonConfigurationInstance
并且该方法自第13级以来已弃用。在您的情况下,您可以很好地删除方法,因为你无论如何都绑定在onStart
......你必须解除绑定onStop
:
@Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
}
根据Service foreground documentation,在前台运行服务与将其绑定为无限制之间没有直接联系。