android - onRetainCustomNonConfigurationInstance 服务泄漏

标签 android

问题
在我的 Activity 中,我绑定(bind)的服务泄漏了。但这只发生在第一次屏幕方向改变之后。在屏幕方向的第二次(及后续)更改中,服务不会泄漏。我无法在onPause 解除绑定(bind)服务,因为服务需要在前台运行(如果您解除绑定(bind)服务,前台将停止)。此外,轮换后,服务仍然有效(我仍然可以调用服务的方法)。

环境
我正在为 midSdkVersion=8targetSdkVersion=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)

最佳答案

如果您查看 FragmentActivity source code 中的 onRetainCustomNonConfigurationInstance您会看到调用 Activity#onRetainNonConfigurationInstance 并且该方法自级别 13 以来已弃用。在您的情况下,您可以很好地删除该方法,因为您无论如何都在 onStart ...并且您必须onStop中取消绑定(bind):

@Override
protected void onStop() {
    super.onStop();
    unbindService(mConnection);
}

根据 Service foreground documentation ,在前台运行服务与是否有界之间没有直接联系。

关于android - onRetainCustomNonConfigurationInstance 服务泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20245623/

相关文章:

java - Android GridLayout 不显示

android - 带文本消息的笑脸将显示在 ListView 中

java - 如何从 PHP JSON 数据填充 ListView fragment ?

android - DownloadManager 完成后移除 toast

android - 确定套接字何时在 Android 上关闭

android - 在Android的“回收器” View 中制作You-tube视频播放器

java - 加载没有 OutOfMemoryError 的大图像

android - Google Analytics 会影响 Android 的性能吗?

android - 如何在 ADB 连接期间禁用电池充电?

android - 自定义 Android 通知磁贴的背景