Android java.lang.IllegalArgumentException: Service non enregistré
J'ai une configuration qui ressemble à quelque chose comme ceci:
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();
}
}
Cependant, je suis toujours de voir l'erreur dans le titre, de temps à autre: java.lang.IllegalArgumentException: Service not registered
être générée lorsque unbindService()
est appelé. Ai-je raté quelque chose de stupide, ou est-il plus? Je note qu'il peut y avoir plus d'un de ce même fragment dans l'existence.
Modifier
Puisque personne ne semble en fait à la lecture du code, laissez-moi vous expliquer. unbindService()
n'appelle pas Context.unbindService(ServiceConnection)
à moins que le service est lié (mBound
) et il n'avait pas été appelé avant la onServiceDisconnected(...)
de rappel a été frappé par un possible appel précédent à unbindService()
.
Que, dans l'esprit, il n'existe aucun cas où Android séparer votre service pour vous tels que le service allait devenir indépendant mais onServiceDisconnected ne serait pas appelé ainsi, me laissant dans un état de l'état?
Aussi, je suis à l'aide de mon contexte de l'Application à faire de la consolidation initiale. Penser à quelque chose comme:
@Override
public void onCreate() {
mApplication = getContext().getApplicationContext();
}
- Si
onSomeEvent()
n'arrive jamais avantonPause()
puis votre service n'est pas lié. - clairement. Avez-vous lu mon code?
- Oui. Vous n'avez pas indiqué où vous initialisez
mAppContext
, quel contexte utilisez-vous? - le contexte de l'application.
mAppContext
est de typeApplication
. - avez-vous trouver la cause ou la solution? Merci à l'avance...
- Je n'ai pas. Nous sorta restructuré un peu de sorte qu'il n'était pas un problème, mais à ce jour je ne sais pas ce qui était en haut.
- J'ai eu le même problème. Cette stackoverflow.com/a/16713212 réponse aidé.
- génial! Qui pourrait expliquer qu'il soit. Merci.
Vous devez vous connecter pour publier un commentaire.
Je me rends compte que cette question a déjà été répondu. Mais je pense qu'il y a de raison d'aller dans lesquelles les gens font cette erreur.
Le vrai problème est, avec la formation docs. http://developer.android.com/reference/android/app/Service.html montre une mise en œuvre correcte tout en https://developer.android.com/guide/components/bound-services.html dans le "ActivityMessenger" montre un Très INCORRECT mise en œuvre.
Dans le "ActivityMessenger' exemple onStop() peut être appelée avant que le service a été effectivement tenus.
La raison de cette confusion, c'est qu'ils sont à l'aide de la borne de service booléen pour signifier différentes choses dans différents exemples. (principalement, a été bindService() appelée OU le Service est-il réellement connecté)
Dans le bon exemples où unbind() est fait sur la base de la valeur de la borne booléen, le booléen indique que le bindService() a été appelé. Puisque c'est la file d'attente pour le thread principal d'exécution, puis unbindService() doit être appelé (donc en attente d'être exécuté), peu importe quand (si jamais) onServiceConnected() se produit.
Dans d'autres exemples, comme celui de http://developer.android.com/reference/android/app/Service.html. Le lien qui indique que les Services est liée, de sorte que vous pouvez l'utiliser et de ne pas obtenir une NullPointerException. Notez que dans cet exemple, le unbindService() l'appel est toujours fait et le lié boolean n'est pas de déterminer si les séparer ou pas.
Utilisation
mIsBound
à l'intérieur dedoBindService()
etdoUnbindService()
au lieu de laServiceConnection
instance.C'est la façon dont c'est fait dans http://developer.android.com/reference/android/app/Service.html
If you have successfully bound to the service, true is returned; false is returned if the connection is not made so you will not receive the service object. However, you should still call unbindService(ServiceConnection) to release the connection.
En d'autres termes, la connexion est faite dès le retour de la méthode, donc après l'appel de cette méthode, vous DEVEZ déconnecter le service.java.lang.IllegalArgumentException: Service not registered
signifie que vous n'êtes pas lié à un service lorsqueunbindService()
a été appelé.Donc dans votre cas,
onSomeEvent()
n'a jamais été appelé avant l'appel àunbindService()
dansonPause()
Une autre raison de cette exception peut être que
unbindService
est appelé par le mauvaisContext
. Parce que les services peuvent être liés non seulement par les Activités, mais aussi par d'autres instances héritée parContext
(à l'exception de BroadcastReceivers), même par d'autres Services, assurez-vous queunbindService
est appelé par le contexte qui l'a lié laService
et non par la limiteService
lui-même. Cela donnerait directement à l'exception ci-dessus "Service non inscrit".Raison?
Si dans votre Activité, unbindService() est appelée avant bindService (), alors vous obtiendrez ce
IllegalArgumentException
.Comment l'éviter?
C'est simple. Vous n'auriez pas besoin d'un drapeau booléen si vous lier et de délier service dans cet ordre.
Lien Pertinent:
Android documentation officielle suggère qui
Si vous avez besoin d'interagir avec le service uniquement pendant que votre activité est visible puis aller avec Solution1.
Si vous souhaitez que votre activité afin de recevoir des réponses, même s'il est arrêté dans la fond puis aller avec Solution2.
J'ai exactement le même problème avec mon application. Chaque maintenant et puis je obtenir
IllegalArgumentException
. Je suppose que le cas spécial est causée lorsque le service est indépendant et laonPause
est appelé avantonServiceDisconnected
. Je voudrais donc essayerSynchronized
choses, pour assurer la bonne exécution.Utilisation: