Domanda

Attualmente sto lavorando su un'app XMPP 'su Android e sto riflettendo sul modo migliore per generare un diverso tipo di eccezione rispetto a RemoteException alla mia attività dal mio servizio.

Poiché sembra impossibile lanciare un'altra cosa rispetto a una RemoteException tramite IPC (non puoi dichiarare di gettare nulla nel tuo .aidl), vedo solo due soluzioni:

  • Crea un listener per la mia attività da ascoltare sulla mia eccezione XMPP personalizzata, che in realtà non verrà generata ma inviata come un normale oggetto che implementa il protocollo Parcelable.

  • Cattura la mia XMPPException e genera una RemoteException (con un contenuto aggiornato con la mia XMPPException) - In tal caso, come potrei sapere sulla mia attività se si tratta di una XMPP o di una vera RemoteException? Taggando il nome dell'eccezione e analizzandolo sulla mia attività? Sarebbe davvero cruento.

Hai qualche idea? Ho perso qualcosa dalla documentazione dell'SDK?

Grazie.

È stato utile?

Soluzione

Se il numero 1 indica quello che penso faccia, lo userei: fare in modo che il servizio rilevi l'eccezione e chiami un metodo su un oggetto callback definito da AIDL creato e fornito dall'attività.

Puoi vedere un esempio di tale tecnica in questo client e service , da uno dei miei libri.

Altri suggerimenti

Sembra che possiamo generare eccezioni personalizzate derivate da RemoteException. Quindi puoi avere XMPPRemoteException o solo una MyRemoteException generica che conterrà l'eccezione originale. Di seguito è una demo per il secondo caso:

Server:

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

Cliente:

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

Metodo di supporto:

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

Eccezione:

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

    public MyRemoteException() {}

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

Penso che sia impossibile ottenere " Gettare un'eccezione personalizzata da un servizio a un'attività " ;. Vedi la risorsa di 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);
}

così possiamo sapere che possiamo semplicemente gettare queste cinque eccezioni sopra.

ad esempio: Se il tuo servizio genera un'eccezione 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!");
    }
...
}

il tuo cliente potrà prenderlo:

            try {
                printer.addImage(0, null);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top