8

Lỗi này dường như xảy ra không thường xuyên, điều này là kỳ quặc. Nó thường hoạt động tốt, nhưng đôi khi nó leo lên. Đây là mã của tôi, mà là ở một BroadcastReceiver:BadParcelableException - BroadcastReceiver intent crash

public void onReceive(Context context, Intent intent) { 
    MyCustomResponseMsg message = new MyCustomResponseMsg((MyMessage) intent.getParcelableExtra(MyMessage.EXTRA_MESSAGE_KEY)); 

    // do stuff with the message 

    setResultCode(Activity.RESULT_OK); 
} 

Và đây là ngoại lệ:

01-16 10:05:03.834: ERROR/AndroidRuntime(13533): FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start receiver com.(path-to-broadcast-receiver).MyReqReceiver: 
android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.(path-to-my-message).MyMessage 
at android.app.ActivityThread.handleReceiver(ActivityThread.java:1805) 
at android.app.ActivityThread.access$2400(ActivityThread.java:117) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:981) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:130) 
at android.app.ActivityThread.main(ActivityThread.java:3683) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:  com.(path-to-my-message).MyMessage 
at android.os.Parcel.readParcelable(Parcel.java:1958) 
at android.os.Parcel.readValue(Parcel.java:1846) 
at android.os.Parcel.readMapInternal(Parcel.java:2083) 
at android.os.Bundle.unparcel(Bundle.java:208) 
at android.os.Bundle.getParcelable(Bundle.java:1100) 
at android.content.Intent.getParcelableExtra(Intent.java:3437) 
at  com.(path).MyReceiver.onReceive(My ReqReceiver.java:23) 
at android.app.ActivityThread.handleReceiver(ActivityThread.java:1794) 
... 10 more 

Các lỗi dường như xảy ra trên dòng getParcelableExtra. Lớp "MyMessage" (rõ ràng được đặt tên một cái gì đó khác nhau trong dự án của riêng tôi) thực sự tồn tại; nó được chứa trong một thư viện. Nó hoạt động hầu hết thời gian, nhưng có những lúc tôi có thể làm cho nó sụp đổ mỗi lần phát sóng được nhận.

Tôi nhận ra điều này không có gì nhiều, nhưng tôi chỉ muốn xem liệu có điều gì tôi có thể làm khác trong bộ thu để nắm bắt điều này sao cho nó không gây ra sự cố. Hoặc nếu nó chắc chắn là một cái gì đó ở phía bên gửi Broadcast, sau đó tôi có thể tập trung vào đó nếu cần thiết. Nhưng trong thời gian tạm thời, tôi chỉ muốn đảm bảo điều này được thiết lập đúng cho mục đích của tôi. Tôi đã kiểm tra các bài viết tương tự khác với sự cố này, nhưng tôi dường như không thể tìm thấy bất kỳ bài viết nào liên quan đến loại nhận được có thể chuyển nhượng cụ thể này từ ý định trong một BroadcastReceiver.

Cảm ơn trước vì đã có hướng dẫn về điều này!

EDIT Đây là những gì các nhà xây dựng cho MyMessage trông như thế nào, nếu cần thiết:

public MyMessage(Parcel in) { 
    field1 = in.readInt(); 
    field2 = in.readString(); 
    field3 = in.readString(); 
} 

Trả lời

8

Hầu hết các trường hợp về vấn đề này tôi đã nhìn thấy đã được giải quyết bằng cách thiết lập đúng ClassLoader trong quá trình unmarshalling lớp tùy chỉnh Parcelable của bạn.

Có một cái nhìn sâu hơn về constructor MyMessage của bạn, đặc biệt là về cách bạn có được ClassLoader:

private MyMessage(Parcel in) { 
    //... 
    //causes ClassNotFoundException 
    this.field=in.readParcelable(null); 
    //causes ClassNotFoundException, in fact it's equivalent to previous 
    this.field=in.readParcelable(ClassLoader.getSystemClassLoader()); 

    //this one should work 
    this.field=in.readParcelable(getClass().getClassLoader()); 
} 

Thông tin chi tiết có thể được tìm thấy in this question.


UPDATE: Ngoài ra, hãy thử cài đặt đúng ClassLoader cho Bundle chứa trong Intent của bạn:

public void onReceive(Context context, Intent intent) { 
    Bundle extras=intent.getExtras(); 
    extras.setClassLoader(getClass().getClassLoader()); 
    MyCustomResponseMsg message = new MyCustomResponseMsg((MyMessage) extras.getParcelable(MyMessage.EXTRA_MESSAGE_KEY)); 
    //... 
} 
+0

Ah có ý nghĩa. Tôi đã cập nhật câu hỏi của mình để thực sự chứa những gì mà hàm tạo trông giống như MyMessage. Dường như mã này chỉ sử dụng các phương thức "readString()" và "readInt()" chuẩn. Tò mò nếu những người đó nên được thay đổi? Tôi rất thận trọng khi làm như vậy, vì lớp MyMessage này được sử dụng ở nhiều nơi khác nhau trong suốt khung ứng dụng của chúng tôi. Vì vậy, tôi hy vọng có một giải pháp mà không liên quan đến việc chạm vào lớp MyMessage? Tôi sẽ đọc sâu hơn trong thời gian đó để tự làm quen với quy trình không sửa đổi. – svguerin3

+0

@ svguerin3 Tôi đã cập nhật câu trả lời của mình, vui lòng xem. –

+0

Thật không may ngay cả khi thêm cài đặt của ClassLoader trong onReceive cho Intent, sự cố vẫn xảy ra với cùng BadParcelableException. :(Bây giờ tôi thực sự bối rối.Tôi đánh giá cao sự giúp đỡ của bạn với điều này bất kể.Bất kỳ ý nghĩ khác, bởi bất kỳ cơ hội? – svguerin3

Các vấn đề liên quan