Генерирует пользовательское исключение из службы в действие

StackOverflow https://stackoverflow.com/questions/1800881

Вопрос

В настоящее время я работаю над приложением XMPP на Android, и я размышляю о лучшем способе создать исключение другого типа, чем RemoteException, для моей активности из моего сервиса.

Поскольку кажется невозможным создать что-то другое, кроме RemoteException, используя IPC (вы не можете объявить, что в вашем .aidl что-либо выбрасывается), я просто вижу два решения:

  • Создайте прослушиватель для моей активности для прослушивания моего пользовательского исключения XMPP, которое на самом деле не будет выдано, а просто отправлено как обычный объект, реализующий Parcelable протокол.

  • Перехватите мое XMPPException и выдайте RemoteException (с содержимым, обновленным с помощью моего XMPPException) - Но в таком случае, как я могу узнать по моей активности, является ли это XMPP или реальным RemoteException ?Пометив имя исключения и проанализировав его в моей активности ?Это было бы действительно ужасно.

У тебя есть какие - нибудь идеи ?Я что - то пропустил из документации SDK ?

Спасибо.

Это было полезно?

Решение

Если # 1 означает то, что я думаю, я бы использовал это - попросил службу перехватить исключение и вызвать метод для объекта обратного вызова, определенного AIDL, созданного и предоставленного activity.

Вы можете увидеть пример этой техники в этом клиент и Обслуживание проект из одной из моих книг.

Другие советы

Похоже, что мы можем создавать пользовательские исключения, производные от RemoteException .Таким образом, у вас может быть XMPPRemoteException или просто общее MyRemoteException, которое будет содержать исходное исключение.Ниже приведена демонстрация для второго случая:

Сервер:

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

Клиент:

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

Вспомогательный метод:

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

Исключение:

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

    public MyRemoteException() {}

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

Я думаю, что невозможно добиться "Выбросить пользовательское исключение из сервиса в действие".Смотрите ресурс Посылки:

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

таким образом, мы можем знать, что мы просто можем выбросить эти пять исключений выше.

например:Если ваш сервис выдает исключение 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!");
    }
...
}

ваш клиент сможет это уловить:

            try {
                printer.addImage(0, null);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top