java – Android中的Bundle的恶魔数量
通过以下代码将数据从一个活动传递给其他活动:
@Override public void execute(List<Report> reports,Questions question) { Intent replyIntent = new Intent(listener,ReplyActivity.class); replyIntent.putExtra("id",0L); replyIntent.putExtra("questions",question); listener.openReportOk(question); listener.startActivity(replyIntent); } 监听其回调的活动引用. 问题是这个类: @Table(name = "Questions") public class Questions extends Entity implements Parcelable { public static final Creator<Questions> CREATOR = new Creator<Questions>() { public Questions createFromParcel(Parcel source) { return new Questions(source); } public Questions[] newArray(int size) { return new Questions[size]; } }; @TableField(name = "idReport",datatype = DATATYPE_INTEGER) private int idReport; @TableField(name = "nameReport",datatype = DATATYPE_STRING) private String nameReport; @TableField(name = "replyGroups",datatype = DATATYPE_STRING) private String replyGroups; @TableField(name = "questionGroups",datatype = DATATYPE_ENTITY) private List<QuestionsGroup> questionsGroup; private Boolean canCreateNew; public Questions(int idReport,String nameReport,String replyGroups,List<QuestionsGroup> questionsGroup) { this.idReport = idReport; this.nameReport = nameReport; this.replyGroups = replyGroups; this.questionsGroup = questionsGroup; this.canCreateNew = false; } public Questions() { questionsGroup = new ArrayList<QuestionsGroup>(); } private Questions(Parcel in) { this(); this.idReport = in.readInt(); this.nameReport = in.readString(); this.replyGroups = in.readString(); Bundle b = in.readBundle(QuestionsGroup.class.getClassLoader()); this.questionsGroup = b.getParcelableArrayList("questionGroups"); this.canCreateNew = (Boolean) in.readValue(Boolean.class.getClassLoader()); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest,int flags) { dest.writeInt(this.idReport); dest.writeString(this.nameReport); dest.writeString(this.replyGroups); Bundle b = new Bundle(); b.putParcelableArrayList("questionGroups",(ArrayList<QuestionsGroup>) this.questionsGroup); dest.writeBundle(b); dest.writeValue(this.canCreateNew); } } 当我在onCreate方法中收到包裹时: private void getData(Intent data) { ID = data.getExtras().getLong("id"); questions = data.getExtras().getParcelable("questions"); } 我得到这个错误: 10-05 13:19:15.508 3499-3499/com.firext.android E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.firext.android,PID: 3499 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.firext.android/com.firext.android.activities.reply.ReplyActivity}: java.lang.IllegalStateException: Bad magic number for Bundle: 0x28 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317) at android.app.ActivityThread.access$800(ActivityThread.java:143) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5070) 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:836) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631) Caused by: java.lang.IllegalStateException: Bad magic number for Bundle: 0x28 at android.os.BaseBundle.readFromParcelInner(BaseBundle.java:1342) at android.os.BaseBundle.<init>(BaseBundle.java:90) at android.os.Bundle.<init>(Bundle.java:66) at android.os.Parcel.readBundle(Parcel.java:1645) at com.firext.android.domain.QuestionsGroup.<init>(QuestionsGroup.java:53) at com.firext.android.domain.QuestionsGroup$1.createFromParcel(QuestionsGroup.java:25) at com.firext.android.domain.QuestionsGroup$1.createFromParcel(QuestionsGroup.java:23) at android.os.Parcel.readParcelable(Parcel.java:2160) at android.os.Parcel.readValue(Parcel.java:2066) at android.os.Parcel.readListInternal(Parcel.java:2422) at android.os.Parcel.readArrayList(Parcel.java:1756) at android.os.Parcel.readValue(Parcel.java:2087) at android.os.Parcel.readArrayMapInternal(Parcel.java:2393) at android.os.BaseBundle.unparcel(BaseBundle.java:221) at android.os.Bundle.getParcelableArrayList(Bundle.java:782) at com.firext.android.domain.Questions.<init>(Questions.java:58) at com.firext.android.domain.Questions.<init>(Questions.java:18) at com.firext.android.domain.Questions$1.createFromParcel(Questions.java:22) at com.firext.android.domain.Questions$1.createFromParcel(Questions.java:20) at android.os.Parcel.readParcelable(Parcel.java:2160) at android.os.Parcel.readValue(Parcel.java:2066) at android.os.Parcel.readArrayMapInternal(Parcel.java:2393) at android.os.BaseBundle.unparcel(BaseBundle.java:221) at android.os.Bundle.getParcelable(Bundle.java:738) at com.firext.android.activities.reply.ReplyActivity.getData(ReplyActivity.java:72) at com.firext.android.activities.reply.ReplyActivity.onCreate(ReplyActivity.java:38) at android.app.Activity.performCreate(Activity.java:5720) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1102) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2208) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317) at android.app.ActivityThread.access$800(ActivityThread.java:143) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5070) 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:836) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631) 怎么了? 解决方法
概要
看起来你有一个错误,你如何存储&检索问题组的混合信息.第53行是要注意的一行. 当写入包裹时,Android会在每个字段中存储一个特殊的“魔术数字”,以确保在将字段从包裹中拉出时使用正确的顺序(请参阅号码定义的详细说明). 您收到错误,因为在预期的位置找不到魔术数字 – 这是因为您没有以正确的顺序将字段从包裹中取出. 官方源代码的详细解释 [下面的解释是基于“最新的”(在撰写本文时)API21实现的Bundle和BaseBundle类.您可以在这里找到完整的代码: > BaseBundle on android.googlesource.com 您还可以使用Android SDK Manager将代码的本地副本安装到开发机器上,我觉得非常有用. ] 所以… 当包裹写入时,Android会采取一些安全措施,以确保在尝试对其进行不分开时,这些字段将排列起来.为此,Android将字段附加到“魔术数字”中,定义为: static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L' 你可以在writeToParcelInner()的代码中看到这一点(总结如下) void writeToParcelInner(Parcel parcel,int flags) { if (mParcelledData != null) { if (mParcelledData == EMPTY_PARCEL) { parcel.writeInt(0); } else { int length = mParcelledData.dataSize(); parcel.writeInt(length); parcel.writeInt(BUNDLE_MAGIC); parcel.appendFrom(mParcelledData,length); } } else { .......... extra code chopped out for illustration purposes } } 同样,当从包裹中读取时,Android会在返回包裹中的值之前检查该BUNDLE_MAGIC号码. private void readFromParcelInner(Parcel parcel,int length) { if (length == 0) { // Empty Bundle or end of data. mParcelledData = EMPTY_PARCEL; return; } int magic = parcel.readInt(); if (magic != BUNDLE_MAGIC) { //noinspection ThrowableInstanceNeverThrown throw new IllegalStateException("Bad magic number for Bundle: 0x" + Integer.toHexString(magic)); } .......... extra code chopped out for illustration purposes } 在上述code for API21 BaseBundle中,您可以看到根据logcat跟踪在第1342行上抛出的错误. 解决方法进一步调试 原始海报指出,QuestionsGroup是正确包装. 进一步调试此问题的一种方法是远离引进BaseBundle类的(当前)新API21;例如,只使用Bundle类的API19. 如果用户的代码实际上是正确的,那么更有可能在更成熟的API上运行. 如果代码仍然中断,则可能是QuestionsGroup代码.但是,除此之外,新的logcat跟踪将指向代码的不同部分,可以查看并可能提供更多的洞察问题. 除了是Bundle,第1730行,方法readFromParcelInner(),这意味着同样的问题: int magic = parcel.readInt(); if (magic != BUNDLE_MAGIC) { //noinspection ThrowableInstanceNeverThrown throw new IllegalStateException("Bad magic number for Bundle: 0x" + Integer.toHexString(magic)); } 相关文章 有关相关信息,请参阅以下帖子: > Android parcelable and Intent: redBundle: bad magic number (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |