views:

750

answers:

2

Hi,

I'm currently working on an XMPP app' on Android and I'm pondering about the best way to throw a different type of Exception than a RemoteException to my activity from my service.

As it seems impossible to throw another thing than a RemoteException using IPC (you can't declare to throw anything in your .aidl), I just see two solutions:

  • Create a listener for my activity to listen on my custom XMPP exception, which in fact will not be thrown but just sent as a usual object implementing the Parcelable protocol.

  • Catch my XMPPException and throw a RemoteException (with a content updated with my XMPPException) - But in that case, how could I know on my activity if it's an XMPP or a real RemoteException ? By tagging the name of the exception and parsing it on my activity ? It would be really gore.

Do you have any idea ? Did I miss something from the SDK documentation ?

Thanks.

A: 

If #1 means what I think it does, I'd use that -- have the service catch the exception and call a method on an AIDL-defined callback object created and supplied by the activity.

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

CommonsWare
Yes, I've taken a look on your code and I was talking about that. I'll use it, it must be the proper way to do that. But it's kinda weird that Google didn't allow us to throw another kind of Exception. Maybe in a future release of the SDK.Thanks for your advice :)
dasilvj
+1  A: 

It looks like we can throw custom exceptions derived from RemoteException. So you can have XMPPRemoteException, or just a generic MyRemoteException that will hold the original exception. Below 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;
}

Exception:

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

    public MyRemoteException() {}

    public MyRemoteException(Exception innerException) {
        this.innerException = innerException;
    }
}
alex2k8
The custom exceptions are good when Service is processing request synchronously. If request is processed asynchronously, than callback to client is to be used (see @commonsware.com response).
alex2k8