Создайте пользовательское исключение из службы для действия - PullRequest
6 голосов
/ 26 ноября 2009

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

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

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

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

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

Спасибо.

Ответы [ 3 ]

5 голосов
/ 26 ноября 2009

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

Вы можете увидеть пример этой техники в этом проекте client и service , из одной из моих книг.

3 голосов
/ 16 декабря 2009

Похоже, мы можем генерировать пользовательские исключения, полученные из 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;
    }
}
0 голосов
/ 14 сентября 2017

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

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