Pergunta

Atualmente, estou trabalhando em um aplicativo XMPP 'no Android e estou pensando na melhor maneira de lançar um tipo diferente de exceção do que uma remoteexception para minha atividade do meu serviço.

Como parece impossível jogar outra coisa além de uma remoteexcepção usando o IPC (você não pode declarar jogar nada no seu .aidl), só vejo duas soluções:

  • Crie um ouvinte para que minha atividade ouça minha exceção personalizada do XMPP, que de fato não será lançada, mas apenas enviada como um objeto usual que implementa o protocolo parcelável.

  • Pegue meu xmppException e jogue uma remoteexception (com um conteúdo atualizado com o meu XMPPEXCIPCE) - mas nesse caso, como eu poderia saber na minha atividade se for um XMPP ou uma remoteexception real? Marcando o nome da exceção e analisando -o na minha atividade? Seria realmente alegre.

Você tem alguma ideia ? Perdi algo da documentação do SDK?

Obrigado.

Foi útil?

Solução

Se #1 significa o que eu acho que faz, eu usaria isso-peça ao serviço a exceção e chamar um método em um objeto de retorno de chamada definido pela AIDL criado e fornecido pela atividade.

Você pode ver um exemplo dessa técnica neste cliente e serviço Projeto, de um dos meus livros.

Outras dicas

Parece que podemos lançar exceções personalizadas derivadas da remoteexception. Assim, você pode ter xmppremoteexception, ou apenas uma miremoteexcepção genérica que manterá a exceção original. Abaixo está uma demonstração para o segundo caso:

Servidor:

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

Cliente:

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

Método Helper:

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

Exceção:

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

    public MyRemoteException() {}

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

Eu acho que é impossível alcançar "Jogue uma exceção personalizada de um serviço para uma atividade". Veja o recurso de 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);
}

Para que possamos saber que podemos apenas lançar essas cinco exceções acima.

Por exemplo: se o seu serviço jogar uma ilegalArgumentException:

    @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!");
    }
...
}

Seu cliente pode pegá -lo:

            try {
                printer.addImage(0, null);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top