Throw a custom service exception into action

I am currently working on an XMPP application on Android, and I am thinking about how to best get a different type of exception from my service than RemoteException.

It seems impossible to throw something other than RemoteException using IPC (you cannot declare that you want to throw something in your .aidl), I just see two solutions:

  • Create a listener for my activity to listen to my custom XMPP exception, which will not actually be thrown, but simply sent as a regular object that implements the Parcelable protocol.

  • Catch my XMPPException and throw a RemoteException (with updated content with my XMPPException). But in this case, how could I find out about my activity if it is XMPP or a real RemoteException? Mark the name of the exception and analyze it in my activity? That would be really great.

Do you have any ideas? Am I missing something from the SDK documentation?

Thanks.

+6
android exception service ipc
source share
3 answers

If # 1 means that I think I am doing this, I would use this - to force the service to catch an exception and call the method on a specific AIDL callback object created and provided by the activity.

You can see an example of this technique in client and service , from one of my books.

+5
source share

It looks like we can throw custom exceptions derived from RemoteException. That way you can have an XMPPRemoteException or just a general MyRemoteException that will contain the original exception. The following is a demo for the second case:

Server:

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

Client:

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

Helper Method:

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

An exception:

 public class MyRemoteException extends RemoteException { private static final long serialVersionUID = 1L; public Exception innerException; public MyRemoteException() {} public MyRemoteException(Exception innerException) { this.innerException = innerException; } } 
+3
source share

I think it is not possible to achieve "Throw a custom exception from a service into action." See Parcel Resource:

  /** * 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); } 

so that we can know that we can simply throw these five exceptions above.

for example: If your service throws an 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!"); } ... } 

your client will be able to catch him:

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

All Articles