Question

Je travaille actuellement sur une application XMPP 'sur Android et je réfléchis au meilleur moyen de créer un type d'exception différent d'une exception RemoteException à mon activité depuis mon service.

Comme il semble impossible de lancer autre chose qu'une exception RemoteException utilisant IPC (vous ne pouvez rien déclarer dans votre fichier .aidl), je ne vois que deux solutions:

  • Créez un écouteur pour mon activité afin d'écouter mon exception XMPP personnalisée, qui ne sera en fait pas générée mais simplement envoyée comme un objet habituel implémentant le protocole Parcelable.

  • Attraper mon exception XMPPException et émettre une RemoteException (avec un contenu mis à jour avec mon exception XMPPException) - Mais dans ce cas, comment savoir si mon activité est un XMPP ou une véritable RemoteException? En marquant le nom de l'exception et en l'analysant dans mon activité? Ce serait vraiment gore.

Avez-vous une idée? Ai-je oublié quelque chose dans la documentation du SDK?

Merci.

Était-ce utile?

La solution

Si # 1 signifie ce que je pense que c'est ce que je pense, je l'emploierais. Le service capterait l'exception et appellerait une méthode sur un objet de rappel défini par AIDL créé et fourni par l'activité.

Vous pouvez voir un exemple de cette technique dans ce client et service de l'un de mes livres.

Autres conseils

Il semble que nous puissions lancer des exceptions personnalisées dérivées de RemoteException. Vous pouvez donc avoir une exception XMPPRemoteException ou simplement une exception générique MyRemoteException qui contiendra l'exception d'origine. Vous trouverez ci-dessous une démo pour le second cas:

Serveur:

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

Client:

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

Méthode d'assistance:

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

Je pense qu'il est impossible de réaliser "Lancer une exception personnalisée d'un service à une activité". Voir la ressource de Parcel:

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

afin que nous sachions que nous pouvons simplement jeter ces cinq exceptions ci-dessus.

par exemple: Si votre service lève une exception 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!");
    }
...
}

votre client pourra l'attraper:

            try {
                printer.addImage(0, null);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top