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

谁说胖子不能爱 提交于 2019-11-28 02:53:16
bdls

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.

Mostafa Rostami

You can use:

@Override
public void onDestroy() {
    super.onDestroy();

    if (mServiceConn != null) {
        unbindService(mServiceConn);
    }
}

You bind in onResume but unbind in onDestroy. You should do the unbinding in onPause instead, so that there are always matching pairs of bind/unbind calls. Your intermittent errors will be where your activity is paused but not destroyed, and then resumed again.

You should only need to unbind the service in onDestroy(). Then, The warning will go.

See here.

As the Activity doc tries to explain, there are three main bind/unbind groupings you will use: onCreate() and onDestroy(), onStart() and onStop(), and onResume() and onPause().

You mention the user switching between Activities pretty quickly. Could it be that you're calling unbindService before the service connection has been established? This may have the effect of failing to unbind, then leaking the binding.

Not entirely sure how you could handle this... Perhaps when onServiceConnected is called you could call unbindService if onDestroy has already been called. Not sure if that'll work though.


If you haven't already, you could add an onUnbind method to your service. That way you can see exactly when your classes unbind from it, and it might help with debugging.

@Override
public boolean onUnbind(Intent intent) {
    Log.d(this.getClass().getName(), "UNBIND");
    return true;
}

Try using unbindService() in OnUserLeaveHint(). It prevents the the ServiceConnection leaked scenario and other exceptions.
I used it in my code and works fine.

You can just controll it with a boolean, so you only call unbind if bind has been made

public void doBindService()
{
    if (!mIsBound)
    {
        bindService(new Intent(this, DMusic.class), Scon, Context.BIND_AUTO_CREATE);
        mIsBound = true;
    }
}

public void doUnbindService()
{
    if (mIsBound)
    {
        unbindService(Scon);
        mIsBound = false;
    }
}

If you only want to unbind it if it has been connected

public ServiceConnection Scon = new ServiceConnection() {

    public void onServiceConnected(ComponentName name, IBinder binder)
    {
        mServ = ((DMusic.ServiceBinder) binder).getService();
        mIsBound = true;
    }

    public void onServiceDisconnected(ComponentName name)
    {
        mServ = null;
    }
};

Every service that is bound in activity must be unbind on app close.

So try using

 onPause(){
   unbindService(YOUR_SERVICE);
   super.onPause();
 }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!