2010-02-21 3 views
10

Ich verwende ein benutzerdefiniertes Parcelable, um einige Daten an einen BroadcastReceiver zu übertragen. Hier ist, was ich tue:ClassNotFoundException bei Verwendung benutzerdefinierter Parcelable

Ich registriere meine Absicht und legen Sie die zusätzliche Parcelable darauf zusammen mit einem zusätzlichen Klassenlader (intent.setExtraClassLoader (..)). Als nächstes plane ich die Ausführung der Sendung über einen AlarmManager.

Also, wenn der AlarmManager feuert, sieht er meine Absicht mit seinem Paket, das es nicht verarbeiten kann, da es den mitgelieferten Klassenlader nicht benutzt (wie es scheint).

Ich denke, der Klassenlader geht verloren, wenn Inten.fillIn die Absicht zu einem neuen kopiert (siehe Stack-Trace).

02-21 21:09:25.214: WARN/Intent(52): android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.company.project.MyParcelable 
02-21 21:09:25.214: WARN/Intent(52):  at android.os.Parcel.readParcelable(Parcel.java:1822) 
02-21 21:09:25.214: WARN/Intent(52):  at android.os.Parcel.readValue(Parcel.java:1713) 
02-21 21:09:25.214: WARN/Intent(52):  at android.os.Parcel.readMapInternal(Parcel.java:1947) 
02-21 21:09:25.214: WARN/Intent(52):  at android.os.Bundle.unparcel(Bundle.java:169) 
02-21 21:09:25.214: WARN/Intent(52):  at android.os.Bundle.putAll(Bundle.java:242) 
02-21 21:09:25.214: WARN/Intent(52):  at android.content.Intent.fillIn(Intent.java:4530) 
02-21 21:09:25.214: WARN/Intent(52):  at com.android.server.am.PendingIntentRecord.send(PendingIntentRecord.java:185) 
02-21 21:09:25.214: WARN/Intent(52):  at android.app.PendingIntent.send(PendingIntent.java:400) 
02-21 21:09:25.214: WARN/Intent(52):  at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:636) 

Also gibt es einen Weg um dieses Problem? Jede Hilfe wäre willkommen.

Dank

Antwort

7

Put com.company.project.MyParcelable in der eigentlichen Anwendung, statt was auch immer Spiele machen Sie mit Classloader spielen. Dann sollte es sowohl vom Absender als auch vom Empfänger der Intent verfügbar sein.

+0

Der Alarmmanager geplant wird, wenn eine BOOT_COMPLETED Aktion empfangen wird. Daher starte ich die Absicht nicht in meiner Anwendung. Gibt es einen besseren Weg, um mit der Situation umzugehen? – Moritz

+4

Oh! Aha. Das habe ich in der Stack-Spur nicht bemerkt. Aus dem Stegreif scheint es, dass Sie kein benutzerdefiniertes "Parcelable" mit einem "PendingIntent" verwenden können, das irgendwie stinkt. Anstatt "Parcelable" zu verwenden, müssen Sie Ihr Objekt möglicherweise auf andere Weise serialisieren (z. B. zu einem 'Bundle', zu einem' String'). – CommonsWare

+0

Ja, die Daten durch ein extra bereites Objekt zu leiten, ist eine Möglichkeit. Das Seltsame ist aber, dass ich die erwähnte Ausnahme bekomme, aber mein Datenobjekt wird tatsächlich übertragen. Es funktioniert also, aber es gibt immer die Ausnahme aus, die verwirrend und bedrohlich ist. – Moritz

6

Es scheint, dass Sie sich mit der Frage konfrontiert hier beschrieben: https://code.google.com/p/android/issues/detail?id=6822

Es gibt eine Abhilfe, die in einem der Kommentare unter diesem Link beschrieben: Ihre benutzerdefinierten Parcelable in eine zusätzliche Bundle setzen. Aufgrund der Tatsache, dass Bundle Interna nicht berührt werden, bis es benötigt wird, kann solch ein Intent an Ihre App geliefert werden, da niemand versuchen wird, Ihre Klasse außerhalb Ihrer App zu entpacken.

Bundle hackBundle = new Bundle(); 
    hackBundle.put("key", myParcelable); 
    intent.putExtra("bundleKey", hackBundle); 
+0

Es gibt eine 'Regel' für das Schlüsselpaket und die Schlüsselabsicht ist anders? – andresmafra

+0

nein, es ist nicht obligatorisch –

+0

Für mich hat es nicht funktioniert.Ich habe versucht, jeden Kommentar hier und in der 6822 Android-Thread Diskussion.Es gibt ein anderes WA? – andresmafra

Verwandte Themen