序列化异常 android.os.BadParcelableException

来源:互联网 发布:将表单数据转成json 编辑:程序博客网 时间:2024/05/22 08:03

1.不要在广播中传递序列化对象

原生存在一个Bug,在系统源码中打开广播调试开关DEBUG_BROADCAST_LIGHT,发送带广播时会去解析extra,解析到序列化对象时系统就崩了,源码如下

          if (DEBUG_BROADCAST_LIGHT) {              int seq = r.intent.getIntExtra("seq", -1);              Slog.i(TAG, "Delivering to " + filter                     + " (seq=" + seq + "): " + r);          }

报错信息:

java.lang.ClassNotFoundException: ClassName
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:309)
at java.lang.Class.forName(Class.java:273)
at android.os.Parcel.readParcelableCreator(Parcel.java:2278)
at android.os.Parcel.readParcelable(Parcel.java:2242)
at android.os.Parcel.readValue(Parcel.java:2149)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2483)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getInt(BaseBundle.java:794)
at android.content.Intent.getIntExtra(Intent.java:5028)
at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:517)
at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:569)
at com.android.server.am.BroadcastQueue$BroadcastHandler.handleMessage(BroadcastQueue.java:149)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
at com.android.server.ServiceThread.run(ServiceThread.java:46)
Caused by: java.lang.ClassNotFoundException: Didn’t find class “ClassName” on path: DexPathList[[directory “.”],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
… 17 more
Suppressed: java.lang.ClassNotFoundException: ClassName
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
… 18 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

当时还很奇怪,为啥会去[directory “.”],nativeLibraryDirectories=[/vendor/lib, /system/lib]中查找类名呢,后来看了下进程后,跟进源码才知道是同事将am的debug开关打开后,接收广播会去解析Extra导致的。


2.确保发送方和接收方序列化对象保持一致

在开发中出现了一个异常,A应用给B应用发送广播,广播中携带序列化对象,这个对象在B应用中序列化实现的是Parcelable接口,在B应用中序列化实现的是Serializable接口于是这时候出现了下面报错

Caused by: android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class ClassName
at android.os.Parcel.readParcelableCreator(Parcel.java:2301)
at android.os.Parcel.readParcelable(Parcel.java:2240)
at android.os.Parcel.readValue(Parcel.java:2147)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2478)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.BaseBundle.getSerializable(BaseBundle.java:988)
at android.os.Bundle.getSerializable(Bundle.java:845)
at ClassName.onReceive(ClassName.java:868)
at android.app.LoadedApkReceiverDispatcherArgs.run(LoadedApk.java:866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5285)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:969)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)

分析异常的时候很纳闷,明明是getSerializable最后为啥报错的时候说缺省了CREATOR属性,后来才发现误接收了B应用的广播,追查后才知道,A应用这部分实现是从B应用那边copy过来的,后来B应用改了下序列化实现方式于是就罪过了

bundle.setClassLoader(getClass().getClassLoader());

0 0
原创粉丝点击