8

Questo errore sembra verificarsi sporadicamente, il che è strano. Di solito funziona bene, ma a volte si insinua. Ecco il mio codice, che è in una 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); 
} 

E qui è l'eccezione:

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 

L'errore sembra verificarsi sulla linea getParcelableExtra. La classe "MyMessage" (ovviamente chiamata qualcosa di diverso nel mio stesso progetto) esiste davvero; è contenuto in una biblioteca. Funziona la maggior parte del tempo, ma ci sono momenti in cui riesco a farlo andare in crash ogni volta che viene ricevuta la trasmissione.

Mi rendo conto che non è molto da cui partire, ma volevo solo vedere se c'era qualcosa che avrei potuto fare diversamente nel ricevitore per catturare questo in modo che non causasse un crash. O se è decisamente qualcosa dalla parte dell'invio della trasmissione, allora posso concentrarmi su quello, se necessario. Ma nel frattempo, volevo solo assicurarmi che fosse configurato correttamente per i miei scopi. Ho controllato altri post simili con questo arresto anomalo, ma non riesco a trovare nessuno che coinvolga questo specifico tipo di parcelable ricavandolo dall'intento di un BroadcastReceiver.

Grazie in anticipo per qualsiasi guida su questo!

EDIT Ecco ciò che il costruttore per MyMessage sembra, se necessario:

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

risposta

8

La maggior parte dei casi di questo problema che ho visto sono stati risolti impostando il corretto ClassLoader nel processo di unmarshalling la tua classe personalizzata Parcelable.

Date un'occhiata più da vicino la vostra MyMessage costruttore, in particolare su come ottenere 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()); 
} 

Maggiori dettagli possono essere trovati in this question.


UPDATE: Inoltre, provare a impostare corretta ClassLoader per Bundle contenute nel vostro Intent:

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 che abbia un senso. Ho aggiornato la mia domanda per contenere effettivamente l'aspetto del costruttore per MyMessage. Sembra che questo codice stia usando solo i metodi standard "readString()" e "readInt()". Curioso se questi dovrebbero essere cambiati? Sarei diffidente a farlo, dal momento che questa classe MyMessage è utilizzata in MOLTI luoghi diversi nel nostro framework applicativo. Quindi spero che ci sia una soluzione che non coinvolga la classe MyMessage? Leggerò più a fondo nel frattempo per familiarizzarmi di più sul processo di smantellamento. – svguerin3

+0

@ svguerin3 Ho aggiornato la mia risposta, per favore date un'occhiata. –

+0

Sfortunatamente anche mentre si aggiunge l'impostazione di ClassLoader nell'onReceive per l'intenzione, l'arresto anomalo si verifica ancora con la stessa eccezione BadParcelable. :(Ora sono davvero perplesso.Apprezzo il tuo aiuto con questo a prescindere.Tutti gli altri pensieri, per caso? – svguerin3