Android中Bundle的错误幻数 [英] Bad magic number for Bundle in Android

查看:759
本文介绍了Android中Bundle的错误幻数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码将数据从一个活动传递到其他活动:

I'm passing data from one activity to other activity with this code:

 @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);
    }

监听器是回调的活动参考。

Listener its a Activity reference for callbacks.

问题是这个课程:

@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方法中收到包裹时:

And when i receive the parcels in onCreate method:

 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)

什么错了?

推荐答案

摘要



看起来你的存储方式有错误&检索 QuestionsGroup 的分区信息。第53行是要注意的行。

Summary

It looks like you have an error in how you store & retrieve the parcelled information of QuestionsGroup. Line 53 is the line to pay attention to.

在写入包裹时,Android会为每个字段存储一个特殊的幻数,以确保您使用正确的将字段从包裹中拉出时的顺序(请参阅数字定义的详细说明)。

When writing to the parcel, Android stores a special "magic number" with each field, to ensure that you use the correct order when pulling fields out of the parcel (see detailed explanation for the definition of the number).

您收到错误,因为在预期中找不到幻数位置 - 这是因为您没有按正确的顺序从包裹中取出字段。

You are getting the error because the magic number is not found in the expected position - this is because you are not taking the fields out of the parcel in the correct order.

[以下说明基于最新(撰写本文时)API21实施捆绑 BaseBundle 类。你可以在这里找到完整的代码:

[ Below explanation is based on the "latest" (at time of writing) API21 implementation of the Bundle and BaseBundle classes. You can find the full code here:

  • BaseBundle on android.googlesource.com

您还可以使用Android SDK Manager将代码的本地副本安装到您​​的开发机器上,我觉得这非常有用。 ]

You can also use the Android SDK Manager to install a local copy of the code onto your development machine, which I find very useful. ]

所以......

当写入包裹时,Android会采取一些安全措施来确保这些字段当你试图取消它们时,排队。要做到这一点,Android会在字段中附加一个幻数,定义为:

When parcels are written, Android takes some security steps to ensure that the fields line up when you try to unparcel them. To do this, Android appends the fields with a "magic number", defined as:

static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'

您可以在代码中看到这一点for writeToParcelInner()(摘要如下)

You can see this in the code for writeToParcelInner() (summarised below)

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, 0, length);
        }
    } else {

   .......... extra code chopped out for illustration purposes

    }
}

同样,从包裹中读取时,Android会检查 BUNDLE_MAGIC 从包裹返回值之前的数字。

Similarly, when reading from the parcel, Android checks for that BUNDLE_MAGIC number before returning the values from the parcel.

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

}

在上面 API21 BaseBundle的代码,你可以看到你的错误是按照logcat跟踪在1342行抛出的。

In the above code for API21 BaseBundle, you can see your error being thrown on line 1342 as per the logcat trace.

原始海报声明 QuestionsGroup 是正确可分辨的。

Original poster states that QuestionsGroup is correctly parcelable.

进一步调试此问题的一种方法是放弃(当前)新的API21,它引入了 BaseBundle 阶级;例如,只使用 Bundle 类的API19。

One way to further debug this issue would be to move away from the (currently) new API21, which introduced the BaseBundle class; down to API19 for example which just uses the Bundle class.

如果用户的代码实际上是正确的,那么它更有可能在更成熟的API上工作。

If the user's code is actually correct, then it is more likely to work on a more mature API.

如果代码仍然中断,则很可能是 QuestionsGroup 代码。但是,此外,新的logcat跟踪将指向代码的不同部分,可以查看并可以更深入地了解问题。

If the code still breaks, it is likely the QuestionsGroup code. However, in addition the new logcat trace will point to a different part of the code, which can be looked at and may provide more insight into the problem.

除非它是从方法 readFromParcelInner()到Bundle,第1730行,这意味着同样的问题:

Unless it is to Bundle, line 1730, from method readFromParcelInner(), which would imply the same problem:

    int magic = parcel.readInt();
    if (magic != BUNDLE_MAGIC) {
        //noinspection ThrowableInstanceNeverThrown
        throw new IllegalStateException("Bad magic number for Bundle: 0x"
                + Integer.toHexString(magic));
    }






相关文章



有关相关信息,请参阅以下帖子:


Related Posts

See the following posts for related information:

  • Android parcelable and Intent: redBundle: bad magic number

这篇关于Android中Bundle的错误幻数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆