У меня есть служба, которая привязана к контексту приложения следующим образом:
getApplicationContext().bindService(
new Intent(this, ServiceUI.class),
serviceConnection,
Context.BIND_AUTO_CREATE
);
protected void onDestroy() {
super.onDestroy();
getApplicationContext().unbindService(serviceConnection);
}
По какой-то причине, только иногда, контекст приложения не привязывается должным образом (я не могу исправить эту часть), однако в onDestroy() я делаю unbindservice
, который выбрасывает ошибку
java.lang.IllegalArgumentException: Service not registered: tools.cdevice.Devices$mainServiceConnection.
Мой вопрос заключается в следующем: есть ли способ безопасно вызвать unbindservice
или проверить, не привязан ли он уже к сервису, прежде чем отвязывать его?
Заранее спасибо.
Попробуйте сделать это:
boolean isBound = false;
...
isBound = getApplicationContext().bindService( new Intent(getApplicationContext(), ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE );
...
if (isBound)
getApplicationContext().unbindService(serviceConnection);
Примечание:
Для привязки и отвязки сервиса следует использовать один и тот же контекст
. Если вы связываете сервис с помощью getApplicationContext()
, то вам также следует использовать getApplicationContext.unbindService(...)
.
Здесь можно найти хорошее объяснение и исходные коды по работе со связанными сервисами. В вашем случае необходимо переопределить методы (onServiceConnected
и onServiceDisconnected
) объекта ServiceConnection
. Тогда вы сможете просто проверить переменную mBound
в своем коде.
Я нашел здесь две проблемы. Пытаясь связать несколько раз и пытаясь разобрать более одного раза.
Решение:
public class ServiceConnectionManager implements ServiceConnection {
private final Context context;
private final Class<? extends Service> service;
private boolean attemptingToBind = false;
private boolean bound = false;
public ServiceConnectionManager(Context context, Class<? extends Service> service) {
this.context = context;
this.service = service;
}
public void bindToService() {
if (!attemptingToBind) {
attemptingToBind = true;
context.bindService(new Intent(context, service), this, Context.BIND_AUTO_CREATE);
}
}
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
attemptingToBind = false;
bound = true;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
bound = false;
}
public void unbindFromService() {
attemptingToBind = false;
if (bound) {
context.unbindService(this);
bound = false;
}
}
}
То, что предложил Андрей Новиков, у меня не сработало. Я просто заменил:
getApplicationContext().unbindService(serviceConnection);
на:
unbindService(serviceConnection);
Я думаю, что руководство - не совсем верно как сказано здесь Чандра Виджая Маджид. Утечка памяти может возникнуть при привязке служба destryed и не подключен еще.
Я думаю, что этот подход:
Service mService;
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
boolean bound = false;
@Override
public void onServiceDisconnected(ComponentName name)
{
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
mService = ((MyService.ServiceBinder) service).getService();
if (!bound)
{
// do some action - service is bound for the first time
bound = true;
}
}
};
@Override
public void onDestroy()
{
if (mService != null)
{
// do some finalization with mService
}
if (mServiceConnection.bound)
{
mServiceConnection.bound = false;
unbindService(mServiceConnection);
}
super.onDestroy();
}
public void someMethod()
{
if (mService != null)
{
// to test whether Service is available, I have to test mService, not mServiceConnection.bound
}
}
Почему мы получаем эту ошибку?
когда вы пытаетесь отменить услугу, которая не зарегистрирована.
Каковы некоторые общие примеры?
больше, чем
привязать(...)` Первый пункт не требует пояснений. Позволяет исследовать второй источник ошибки более глубоко. Отладка помощью bind() и unbind() звонки. Если вы видите звонки в этих целях, то ваша заявка будет в конечном итоге получить IllegalArgumentException
.
Как мы можем избежать этого? Существует два способа, которые вы должны рассмотреть, чтобы связывать и развязывать службы в деятельности. Документы андроид рекомендуем
bindService() в функции onStart () и unbindService() в методе onStop()`
Your Activity {
@Override
public void onStart(){
super.onStart();
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
@Override
public void onStop(){
super.onStop();
unbindService(mConnection);
}
}
bindService() в методе onCreate () и unbindService() в onDestroy()`
Your Activity {
@Override
public void onCreate(Bindle sis){
super.onCreate(sis);
....
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
Не уверен, что все вышеуказанные ответы, казалось слишком сложным, хотя ни один из этих подошел бы вопрос у меня не было.
Только связать/развязать один раз в то время, и обслуживание было определенно связаны на время уберите() вызова. Дон'т хотите выложить что-нибудь, поэтому я просто уверен, что я, используя тот же контекст для помощью bind() и unbind() вызовы, и это решено окончательно! Делать что-то вроде этого:
any_context.getApplicationContext().bind(...);
...
another_context.getApplicationContext().unbind(...);