سؤال

أنا أعمل حاليًا على تطبيق XMPP على Android وأنا أفكر في أفضل طريقة لرمي نوع مختلف من الاستثناءات عن RemoteException على نشاطي من خدمتي.

نظرًا لأنه من المستحيل إلقاء شيء آخر غير RemoteException باستخدام IPC (لا يمكنك إعلان رمي أي شيء في .edl) ، أرى فقط حلين:

  • قم بإنشاء مستمع لنشطتي للاستماع إلى استثناء XMPP المخصص الخاص بي ، والذي لن يتم إلقاؤه في الواقع ولكن تم إرساله ككائن معتاد ينفذ بروتوكول الطرود.

  • التقط XMPPException ورمي جهازًا عن بعد (مع محتوى تم تحديثه باستخدام XMPPException) - ولكن في هذه الحالة ، كيف يمكنني أن أعرف في نشاطي إذا كان XMPP أو REMOTEXCESTION حقيقيًا؟ من خلال وضع علامة على اسم الاستثناء وحلله على نشاطي؟ سيكون حقا غور.

هل لديك أي فكرة ؟ هل فاتني شيء من وثائق SDK؟

شكرًا.

هل كانت مفيدة؟

المحلول

إذا كان #1 يعني ما أعتقد أنه يفعل ذلك ، فسأستخدم ذلك-اطلب من الخدمة التقاط الاستثناء واستدعاء طريقة على كائن رد اتصال محدد من قبل AIDL تم إنشاؤه وتوفيره بواسطة النشاط.

يمكنك رؤية مثال على هذه التقنية في هذا عميل و الخدمات المشروع ، من أحد كتبي.

نصائح أخرى

يبدو أنه يمكننا رمي استثناءات مخصصة مشتقة من 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);
}

لذلك يمكننا أن نعرف أنه يمكننا فقط رمي هذه الاستثناءات الخمسة أعلاه.

على سبيل المثال: إذا كانت خدمتك ترمي غير شرعي:

    @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