Notificar a un servicio de Android cuando un cliente vinculado se desconecta

Tengo un servicio androide en un proceso remoto que puede tener múltiples enlaces de diferentes clientes. Mi pregunta es, ¿cómo puede notificarse el servicio cuando un cliente vinculado específico se desconecta inesperadamente (es decir, el cliente se ha estrellado)? No puedo usar onUnbind() , porque sólo se llama después de que todos los clientes se han desconectado.

 public class MyService extends Service { final Messenger mServiceMessenger = new Messenger(new IncomingHandler()); @Override public IBinder onBind(Intent intent) { return mServiceMessenger.getBinder(); } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return Service.START_STICKY; } class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { // Handling messages logic... } } } 

Puede utilizar el manejador IncomingHandler que tiene y enviar un mensaje desde el cliente que será unbinded antes de llamar unbindService (serviceConnection), manteniendo arraylist de los mensajeros (clientes) y agregar / quitar cuando se recibe un mensaje.

También puede intentar enviar mensajes falsos y si recibe RemoteException significa que el cliente remoto está muerto.

Compruebe este ejemplo http://developer.android.com/reference/android/app/Service.html

extraer:

 class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: mValue = msg.arg1; for (int i=mClients.size()-1; i>=0; i--) { try { mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, mValue, 0)); } catch (RemoteException e) { // The client is dead. Remove it from the list; // we are going through the list from back to front // so this is safe to do inside the loop. mClients.remove(i); } } break; default: super.handleMessage(msg); } } } 

Esto se puede hacer por el mecanismo Binder.linkToDeath() – Tendrá que pedir a cada cliente que envíe un new Binder() objeto new Binder() que inició y luego enlazar con su muerte (de sus clientes). Voy a explicar cómo hacer esto utilizando los archivos AIDL .

(Usted puede elegir cualquier mecanismo del IPC del androide mientras usted pueda pasar los objetos de la carpeta de su cliente a su servicio)

Ejemplo de código –

Dentro de su archivo .AIDL – Cree un método para pasar el objeto IBinder desde el cliente al servicio

 void registerProcessDeath(in IBinder clientDeathListener, String packageName); 

En el lado del cliente – Inicialice un nuevo objeto y lo pasará a su servicio a través de la interfaz AIDL.

 public void onServiceConnected(ComponentName className, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); //Call the registerProcessDeath method from the AIDL file and pass //the new Binder object and the client's package name mIMyAidlInterface.registerProcessDeath(new Binder(),getPackageName()); } 

En el lado del servicio

1. Obtener la Binder del cliente y registrarse en su linkToDeath() .
2. Utilizar la clase auxiliar para manejar todos los clientes a través de la clase IBinder.DeathRecipient de android

 public class MyService extends Service { //Helper class to handle all client's deaths. private volatile ClientsDeathWatcher mClientsList; @Override public IBinder onBind(Intent intent) { mClientsList = new ClientsDeathWatcher(); return mStub; } private final IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() { @Override public void registerProcessDeath(IBinder cb, String packageName){ boolean isRegistered = mClientsList.register(cb , packageName); } }; } //This is thread-safe helper class to handle all //the client death related tasks. //All you care abut is the clientDeath() method. public class ClientsDeathWatcher { private ArrayMap<String, DeathCallBack> mCallbacks = new ArrayMap<>(); private final class DeathCallBack implements IBinder.DeathRecipient { private String pn; private IBinder mBinder; DeathCallBack(String packageName,IBinder binder) { pn = packageName; mBinder = binder; } public void binderDied() { synchronized (mCallbacks) { mBinder.unlinkToDeath(this,0); clientDeath(pn); } } } //To be called only from thread-safe functions private void clientDeath(String packageName) { mCallbacks.remove(packageName); //Do your stuff here. //$$$$$$$$$ } public boolean register(IBinder token, String packageName) { synchronized (mCallbacks) { try { if (!mCallbacks.containsKey(packageName)) { DeathCallBack mDeathCallBack = new DeathCallBack(packageName,token); mCallbacks.put(packageName, mDeathCallBack); //This is where the magic happens token.linkToDeath(mDeathCallBack, 0); } return true; } catch (RemoteException e) { e.printStackTrace(); return false; } } } } 
  • Tratando de conectar la aplicación de Android a .NET ".svc" webservice y el servidor responde Tipo de soporte no compatible
  • Comprobar si los datos de campo han cambiado en lugar de cualquier campo en los datos secundarios
  • START_STICKY, el servicio Android de primer plano desaparece sin previo aviso
  • Excepción de puntero nulo que hace difícil pasar un arreglo usando ksoap
  • Cómo obtener actividad en el servicio de intención
  • ¿Cómo enviar notificaciones a la aplicación de Android desde el servidor de Java mediante GCM?
  • No puedo conectarme a mi servicio web
  • Función "Battery saver" matando mi servicio de música
  • Error en Callin Java webservice de Android usando k-Soap
  • Cómo tratar un objeto JSON grande en Android
  • ¿Qué es un servicio web en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.