サービスからアクティビティにカスタム例外をスローします
質問
現在、AndroidでXMPPアプリに取り組んでおり、サービスからのアクティビティに対してRemoteExceptionとは異なるタイプの例外をスローする最良の方法について考えています。
IPCを使用してRemoteException以外のものをスローすることは不可能と思われるため(.aidlで何もスローすることは宣言できません)、2つの解決策があります:
-
アクティビティのリスナーを作成して、カスタムXMPP例外をリッスンします。実際にはスローされず、Parcelableプロトコルを実装する通常のオブジェクトとして送信されます。
-
XMPPExceptionをキャッチして、RemoteExceptionをスローします(コンテンツがXMPPExceptionで更新されます)-しかし、その場合、XMPPまたは実際のRemoteExceptionである場合、アクティビティをどのように知ることができますか?例外の名前にタグを付けて、アクティビティで解析するそれは本当にマチでしょう。
アイデアはありますか? SDKドキュメントから何かを見逃しましたか?
ありがとう。
他のヒント
RemoteExceptionから派生したカスタム例外をスローできるようです。したがって、XMPPRemoteException、または元の例外を保持する一般的なMyRemoteExceptionのみを持つことができます。以下は2番目のケースのデモです:
サーバー:
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;
}
}
「サービスからアクティビティにカスタム例外をスロー」を達成することは不可能だと思います。 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);
}
したがって、上記の5つの例外をスローできることを知ることができます。
例: サービスが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();
}