Android java.ленг.IllegalArgumentException: служба не зарегистрирована
у меня есть настройка, которая выглядит примерно так:
class MyFragment implements SomeEventListener {
Application mAppContext;
boolean mBound;
boolean mDidCallUnbind;
MyIBinder mBinder;
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBound = true;
mBinder = (MyIBinder) service;
mBinder.getThings();...
}
@Override
public void onServiceDisconnected(ComponentName name) {
mDidCallUnbind = false;
mBound = false;
mBinder = null;
}
};
...
@Override
public void onSomeEvent() {
mAppContext.bindService(...);
}
void unbindService() {
if (mBound && !mDidCallUnbind) {
mDidCallUnbind = true;
mAppContext.unbindService(mConnection);
}
}
@Override
public void onPause() {
unbindService();
super.onPause();
}
}
тем не менее, я все еще вижу ошибку в названии время от времени: java.lang.IllegalArgumentException: Service not registered
на unbindService()
называется. Я упускаю что-то глупое, или происходит что-то еще? Я должен отметить, что может существовать несколько таких фрагментов.
редактировать
поскольку никто на самом деле, кажется, не читает код, позвольте мне объяснить. unbindService()
не называет Context.unbindService(ServiceConnection)
если услуга (mBound
) и раньше он не вызывался до onServiceDisconnected(...)
обратный вызов был поражен от возможного предыдущего вызова unbindService()
.
что в виду, есть ли какие-либо случаи, когда Android будет развязать вашу службу для вас, так что служба станет несвязанной, но onServiceDisconnected не будет называться таким образом, оставляя меня в устаревшем состоянии?
кроме того, я использую контекст приложения для выполнения начальной привязки. Предположим, что-то вроде:
@Override
public void onCreate() {
mApplication = getContext().getApplicationContext();
}
5 ответов
Я понимаю, этот вопрос уже ответили. Но я думаю, что есть причина, по которой люди совершают эту ошибку.
проблема действительно в учебных документах. http://developer.android.com/reference/android/app/Service.html показывает правильную реализацию в то время как https://developer.android.com/guide/components/bound-services.html в "ActivityMessenger" показывает очень неправильно реализация.
In пример "ActivityMessenger" onStop () потенциально может быть вызван до фактической привязки службы.
причина этой путаницы заключается в том, что они используют boolean bound service для обозначения разных вещей в разных примерах. (в основном, был вызван bindService () или служба фактически подключена)
в правильных примерах, где unbind () выполняется на основе значения bound boolean, bound boolean указывает, что bindService() был называется. Поскольку он находится в очереди для выполнения основного потока, необходимо вызвать unbindService () (так что очередь должна быть выполнена), независимо от того, когда (если когда-либо) onServiceConnected() происходит.
в других примерах, таких как один в http://developer.android.com/reference/android/app/Service.html. Граница указывает, что службы фактически связаны, так что вы можете использовать его и не получить исключение NullPointerException. Обратите внимание, что в этом примере unbindService() вызов еще и bound boolean не определяет, следует ли развязывать или нет.
использовать mIsBound
внутри doBindService()
и doUnbindService()
вместо ServiceConnection
экземпляра.
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = (MyIBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBinder = null;
}
};
...
public void doBindService() {
bindService(new Intent(this, MyService.class),
mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
public void doUnbindService() {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
}
}
вот как это делается в http://developer.android.com/reference/android/app/Service.html
java.lang.IllegalArgumentException: Service not registered
означает, что вы не были обязаны обслуживать, когда unbindService()
называлась.
Итак, в вашем случае,onSomeEvent()
никогда не вызывался до вызова unbindService()
на onPause()
другой возможной причиной этого исключения может быть то, что unbindService
вызывается неправильным Context
. Потому что службы могут быть связаны не только действиями, но и другими экземплярами, унаследованными Context
(за исключением BroadcastReceivers), даже другими службами, убедитесь, что unbindService
вызывается контекстом, который связал Service
и не связаны . Это приведет непосредственно к вышеуказанному исключению "служба не зарегистрирована".
у меня точно такая же проблема с моим приложением. Время от времени я получаю IllegalArgumentException
. Я предполагаю, что особый случай вызван, когда служба развязана и onPause
называется до onServiceDisconnected
. Поэтому я бы попробовал Synchronized
для обеспечения правильного выполнения.