2009-11-26 22 views
6

Actualmente estoy trabajando en una aplicación XMPP 'en Android y estoy reflexionando sobre la mejor manera de lanzar un tipo diferente de excepción que una excepción remota a mi actividad de mi servicio .Lanzar una excepción personalizada de un servicio a una actividad

Como parece imposible tirar otra cosa que un RemoteException usando IPC (no se puede declarar a tirar nada en su .aidl), sólo veo dos soluciones:

  • crear un escucha para mi actividad para escuchar en mi excepción XMPP personalizada, que de hecho no se lanzará, sino que se enviará como un objeto habitual que implementa el protocolo Parcelable.

  • Captura mi XMPPException y lanzo una RemoteException (con un contenido actualizado con mi XMPPException) - Pero en ese caso, ¿cómo podría saber sobre mi actividad si se trata de un XMPP o una RemoteException real? ¿Etiquetando el nombre de la excepción y analizándolo en mi actividad? Sería realmente gore.

¿Alguna idea? ¿Extrañé algo de la documentación del SDK?

Gracias.

+0

No se olvide de aceptar una respuesta si uno de ellos trabajaron para usted. Ayuda a los futuros televidentes a saber qué respuesta te ayudó más.Gracias – prolink007

Respuesta

5

Si # 1 significa lo que creo que es, lo usaría - haga que el servicio capte la excepción y llame a un método en un objeto de devolución de llamada definido por AIDL creado y provisto por la actividad.

Puede ver un ejemplo de esa técnica en este proyecto client y service, de uno de mis libros.

+0

Sí, he echado un vistazo a su código y estaba hablando de eso. Lo usaré, debe ser la forma correcta de hacerlo. Pero es un poco extraño que Google no nos permita lanzar otro tipo de excepción. Tal vez en una versión futura del SDK. Gracias por su consejo :) – dasilvj

3

Parece que podemos lanzar excepciones personalizadas derivadas de RemoteException. Entonces puede tener XMPPRemoteException, o simplemente una MyRemoteException genérica que contendrá la excepción original. A continuación se muestra una demo para el segundo caso:

Servidor:

try { 
    ... 
} 
catch(XMPPException e) { 
    throw new MyRemoteException(e); 
} 

Cliente:

try { 
    service.someCall(); 
} 
catch(MyRemoteException e) { 
    rethrow(e); 
} 

método Ayudante:

private void rethrow(MyRemoteException e) throws Exception { 
    if(e.innerException instanceof XMPPException) 
     throw (XMPPException)e.innerException; 
    else 
     throw e.innerException; 
} 

Excepción:

public class MyRemoteException extends RemoteException { 
    private static final long serialVersionUID = 1L; 
    public Exception innerException; 

    public MyRemoteException() {} 

    public MyRemoteException(Exception innerException) { 
     this.innerException = innerException; 
    } 
} 
+0

Las excepciones personalizadas son buenas cuando el Servicio está procesando la solicitud de forma síncrona. Si la solicitud se procesa de manera asíncrona, se utilizará la devolución de llamada al cliente (consulte la respuesta de @ commonsware.com). – alex2k8

+0

E/JavaBinder (1544): *** excepción remota no capturada! (Todavía no se admiten excepciones en los procesos). Este enfoque no funciona para mí. – user1074896

+1

Tampoco funciona para mí. MyRemoteException será capturado por el framework y se registrará, y se generará una nueva RemoteException no relacionada en el extremo del cliente. Votando abajo esta respuesta. – TommyTh

0

Creo que es imposible lograr "Lanzar una excepción personalizada de un servicio a una actividad". Ver el recurso de la Parcela:

/** 
* Use this function for customized exception handling. 
* customized method call this method for all unknown case 
* @param code exception code 
* @param msg exception message 
*/ 
public final void readException(int code, String msg) { 
    switch (code) { 
     case EX_SECURITY: 
      throw new SecurityException(msg); 
     case EX_BAD_PARCELABLE: 
      throw new BadParcelableException(msg); 
     case EX_ILLEGAL_ARGUMENT: 
      throw new IllegalArgumentException(msg); 
     case EX_NULL_POINTER: 
      throw new NullPointerException(msg); 
     case EX_ILLEGAL_STATE: 
      throw new IllegalStateException(msg); 
    } 
    throw new RuntimeException("Unknown exception code: " + code 
      + " msg " + msg); 
} 

por lo que podemos saber que nos podemos tirar estos cinco excepciones anteriormente.

por ejemplo: Si el servicio de lanzar una IllegalArgumentException:

@Override 
public void addImage(final int align, final byte[] imageData) throws RemoteException { 
    log("/// addImage ///"); 
    if (imageData == null) { 
     throw new IllegalArgumentException("The second argument(image data) can not be empty!"); 
    } 
... 
} 

su cliente se puede cogerlo:

  try { 
       printer.addImage(0, null); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } 
Cuestiones relacionadas