studio programacion móviles desarrollo curso aplicaciones android android-service android-service-binding

programacion - Android java.lang.IllegalArgumentException: Servicio no registrado



manual de programacion android pdf (5)

Tengo una configuración que se parece a esto:

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(); } }

Sin embargo, todavía estoy viendo el error en el título de vez en cuando: java.lang.IllegalArgumentException: Service not registered se genera cuando se llama a unbindService() . ¿Me estoy perdiendo algo tonto, o hay algo más? Debo señalar que puede haber más de uno de este mismo fragmento en existencia.

Editar

Ya que nadie parece estar leyendo el código, déjame explicarte. unbindService() no llama a Context.unbindService(ServiceConnection) menos que el servicio esté vinculado ( mBound ) y no haya sido llamado previamente antes de la onServiceDisconnected(...) llamada onServiceDisconnected(...) de una posible llamada previa a unbindService() .

Teniendo esto en cuenta, ¿hay casos en los que Android desvincule su servicio para usted de manera tal que el servicio se desvincule pero no se llame a OnServiceDisconnected dejándome en un estado obsoleto?

Además, estoy usando el contexto de mi Aplicación para hacer el enlace inicial. Supongamos algo como:

@Override public void onCreate() { mApplication = getContext().getApplicationContext(); }


Me doy cuenta de que esta pregunta ya ha sido respondida. Pero creo que hay razones para explicar por qué la gente está cometiendo este error.

El problema es realmente con los documentos de formación. http://developer.android.com/reference/android/app/Service.html muestra una implementación correcta, mientras que https://developer.android.com/guide/components/bound-services.html en el ''ActivityMessenger'' muestra una Implementación muy INCORRECTA .

En el ejemplo de ''ActivityMessenger'', se puede llamar a onStop () antes de que el servicio haya sido realmente vinculado.

La razón de esta confusión es que están utilizando el servicio booleano enlazado para significar cosas diferentes en diferentes ejemplos. (principalmente, se llamó bindService () llamado OR si el Servicio está realmente conectado)

En los ejemplos correctos en los que se realiza unbind () en función del valor del booleano enlazado, el booleano enlazado indica que se ha llamado al bindService () . Ya que está en cola para la ejecución del subproceso principal, entonces debe invocarse a unbindService () (para que se ponga en cola), independientemente de cuándo (si alguna vez) sucede onServiceConnected ().

En otros ejemplos, como el de http://developer.android.com/reference/android/app/Service.html . El límite indica que los Servicios están realmente vinculados para que pueda usarlo y no obtener una NullPointerException. Tenga en cuenta que en este ejemplo, la llamada unbindService () aún se realiza y el booleano enlazado no determina si se debe desvincular o no .


Otra posible razón para esta excepción podría ser que el Context incorrecto llama a unbindService . Debido a que los servicios pueden estar vinculados no solo por Actividades, sino también por otras instancias heredadas por Context (con la excepción de BroadcastReceivers), incluso por otros Servicios, asegúrese de que unbindService sea ​​llamado por el contexto que ha vinculado al Service y no por el enlace Service sí. Esto daría directamente la excepción anterior "Servicio no registrado".


Tengo exactamente el mismo problema con mi aplicación. De vez en cuando me sale IllegalArgumentException . Supongo que el caso especial se produce cuando el servicio no está onPause se llama a onServiceDisconnected antes de onServiceDisconnected . Así que intentaría cosas Synchronized para asegurar la correcta ejecución.


Utilice mIsBound dentro de doBindService() y doUnbindService() lugar de en la instancia de 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; } }

Así es como se hace en http://developer.android.com/reference/android/app/Service.html


java.lang.IllegalArgumentException: Service not registered significa que no estaba obligado a prestar servicio cuando se llamó a unbindService() .

En su caso, nunca se llamó a unbindService() antes de llamar a unbindService() en onPause()