2009-11-26 2 views
6

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

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

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

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

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

Спасибо.

+0

Не забудьте принять ответ, если один их работал для вас. Это помогает будущим зрителям узнать, какой ответ вам больше всего помог.Спасибо – prolink007

ответ

5

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

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

+0

Да, я взглянул на ваш код, и я говорил об этом. Я буду использовать его, это должен быть правильный способ сделать это. Но это странно, что Google не позволял нам выбрасывать другой вид Exception. Возможно, в будущем выпуске SDK. Спасибо за ваш совет :) – dasilvj

3

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

Сервер:

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

Клиент:

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

метод Helper:

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

Пользовательские исключения хороши, когда служба обрабатывает запрос синхронно. Если запрос обрабатывается асинхронно, необходимо использовать обратный вызов для клиента (см. Ответ @ commonsware.com). – alex2k8

+0

E/JavaBinder (1544): *** Неоткрытое удаленное исключение! (Исключения пока не поддерживаются в разных процессах.) Этот подход не работает для меня. – user1074896

+1

Это тоже не работает для меня. Исключение MyRemoteException будет захвачено каркасом и зарегистрировано, а новое несвязанное RemoteException будет создано на стороне клиента. Проголосовать за этот ответ. – TommyTh

0

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

/** 
* 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(); 
      } 
Смежные вопросы