Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Parcelable bad array lengths

Parcelables. Why can't they be more easy? I'm trying to write an application which sends an ArrayList as a parcelable. When I try to get the Intent in the second Activity, I'll get the error:

12-29 21:36:08.158: W/System.err(20117): java.lang.RuntimeException: bad array lengths
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readStringArray(Parcel.java:967)
12-29 21:36:08.158: W/System.err(20117):    at net.sutomaji.sv.helperclasses.NewsItem.<init>(NewsItem.java:102)
12-29 21:36:08.158: W/System.err(20117):    at net.sutomaji.sv.helperclasses.NewsItem$1.createFromParcel(NewsItem.java:129)
12-29 21:36:08.158: W/System.err(20117):    at net.sutomaji.sv.helperclasses.NewsItem$1.createFromParcel(NewsItem.java:1)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readParcelable(Parcel.java:2104)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readValue(Parcel.java:2013)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readListInternal(Parcel.java:2343)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readArrayList(Parcel.java:1703)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readValue(Parcel.java:2034)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Bundle.unparcel(Bundle.java:249)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Bundle.getParcelableArrayList(Bundle.java:1250)
12-29 21:36:08.158: W/System.err(20117):    at android.content.Intent.getParcelableArrayListExtra(Intent.java:4680)
12-29 21:36:08.158: W/System.err(20117):    at net.sutomaji.sv.MainActivity.onCreate(MainActivity.java:104)
12-29 21:36:08.158: W/System.err(20117):    at android.app.Activity.performCreate(Activity.java:5241)
12-29 21:36:08.158: W/System.err(20117):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
12-29 21:36:08.158: W/System.err(20117):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
12-29 21:36:08.158: W/System.err(20117):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2248)
12-29 21:36:08.158: W/System.err(20117):    at android.app.ActivityThread.access$800(ActivityThread.java:138)
12-29 21:36:08.158: W/System.err(20117):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Handler.dispatchMessage(Handler.java:102)
12-29 21:36:08.158: W/System.err(20117):    at android.os.Looper.loop(Looper.java:136)
12-29 21:36:08.158: W/System.err(20117):    at android.app.ActivityThread.main(ActivityThread.java:5050)
12-29 21:36:08.168: W/System.err(20117):    at java.lang.reflect.Method.invokeNative(Native Method)
12-29 21:36:08.168: W/System.err(20117):    at java.lang.reflect.Method.invoke(Method.java:515)
12-29 21:36:08.168: W/System.err(20117):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
12-29 21:36:08.168: W/System.err(20117):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
12-29 21:36:08.168: W/System.err(20117):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:126)
12-29 21:36:08.168: W/System.err(20117):    at dalvik.system.NativeStart.main(Native Method)

I've tried Strings instead of a Parcelable arraylist, this will work. Even if I get the ArrayList after setting the items, it will work:

mainIntent.putParcelableArrayListExtra("items", items);
for(Parcelable p : mainIntent.getParcelableArrayListExtra("items")) {
  NewsItem ni = (NewsItem) p;
  Log.v(TAG, ni.getName());
}

But as I want to get the arraylist in the second activity, I get the previous error:

for(Parcelable p : getIntent().getParcelableArrayListExtra("items")) {
  NewsItem ni = (NewsItem) p;
  Log.v(TAG, ni.getName());
}

What could be the error? And here is my NewsItem class if u need this:

package net.sutomaji.sv.helperclasses;

imports...

public class NewsItem implements Parcelable {

    private int id;
    private String name;
    private String bubble;
    private String drawable;
    private String title;
    private String summary;
    private String description;

    public NewsItem() {
        this.bubble = "";
        this.drawable = null;
        this.title = "";
        this.summary = "";
        this.id = -1;
        this.name = "";
        this.description = "";
    }

    public NewsItem(int id, String name, String bubble, String drawable, String title, String summary, String description) {
        this.id = id;
        this.bubble = bubble;
        this.drawable = drawable;
        this.title = title;
        this.summary = summary;
        this.name = name;
        this.description = description;
    }


    getters and setters...

    /* PARCELLING STUFF....................... */
    public NewsItem(Parcel in) {
        String[] data = new String[6];

        in.readStringArray(data);
        in.readInt();

        this.name = data[0];
        this.bubble = data[1];
        this.drawable = data[2];
        this.title = data[3];
        this.summary = data[4];
        this.description = data[5];
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeStringArray(new String[] {
                this.name, this.bubble, this.drawable,
                this.title, this.summary, this.description
        });
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public NewsItem createFromParcel(Parcel in) {
            return new NewsItem(in); 
        }

        public NewsItem[] newArray(int size) {
            return new NewsItem[size];
        }
    };
}
like image 425
vigonotion Avatar asked Dec 29 '13 20:12

vigonotion


1 Answers

You need to read from the Parcel in the same order in which you wrote things. You are writing this.id first, but you are attempting to read the string array before reading the id. Reverse the order of the calls in either the constructor or writeToParcel.

Also, instead of writing a string array, why not just write each string individually? Seems a lot simpler.

public NewsItem(Parcel in) {
    in.readInt();
    this.name = in.readString();
    this.bubble = in.readString();
    this.drawable = in.readString();
    this.title = in.readString();
    this.summary = in.readString();
    this.description = in.readString();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(this.id);
    dest.writeString(this.name);
    dest.writeString(this.bubble);
    dest.writeString(this.drawable);
    dest.writeString(this.title);
    dest.writeString(this.summary);
    dest.writeString(this.description);
}
like image 92
Ted Hopp Avatar answered Oct 13 '22 09:10

Ted Hopp