简体   繁体   中英

Class Parcelable with ArrayList of Objects

I'm trying to use Parcelable on a class that contains ArrayList of Objects.

I'm getting an error when trying to write the list.

the class -

public class Library implements Parcelable {

ArrayList<Station> stations;
private String[] stationNames;
private String[] stationsDescription;
private int[] images;
private String[] streamLinks;

public Library(String[] stationNames, String[] stationsDescription, int[] images, String[] streamLinks) {
    //instantiationCounter++;
    this.stationNames = stationNames;
    this.stationsDescription = stationsDescription;
    this.images = images;
    this.streamLinks = streamLinks;

    this.stations = new ArrayList<>();

    for (int i = 0; i < stationNames.length; i++) {
        stations.add(new Station(stationNames[i], stationsDescription[i], streamLinks[i], images[i]));
    }
}

public Library() {
}

protected Library(Parcel in) {
    stationNames = in.createStringArray();
    stationsDescription = in.createStringArray();
    images = in.createIntArray();
    streamLinks = in.createStringArray();
    stationNames = in.createStringArray();
    stations = in.readArrayList(null);

}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeStringArray(stationNames);
    dest.writeStringArray(stationsDescription);
    dest.writeIntArray(images);
    dest.writeStringArray(streamLinks);
    dest.writeList(stations);
}

Logcat -

java.lang.RuntimeException: Parcel: unable to marshal value com.tsuryohananov.israeliradio.Station@8b5e126 at android.os.Parcel.writeValue(Parcel.java:1711) at android.os.Parcel.writeList(Parcel.java:865) at com.tsuryohananov.israeliradio.Library.writeToParcel(Library.java:65) at android.os.Parcel.writeParcelable(Parcel.java:1730) at android.os.Parcel.writeValue(Parcel.java:1636) at android.os.Parcel.writeArrayMapInternal(Parcel.java:777) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1506) at android.os.Bundle.writeToParcel(Bundle.java:1181) at android.os.Parcel.writeBundle(Parcel.java:817) at android.content.Intent.writeToParcel(Intent.java:9480) at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:4877) at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1491) at android.app.ContextImpl.startService(ContextImpl.java:1461) at android.content.ContextWrapper.startService(ContextWrapper.java:644) at com.tsuryohananov.israeliradio.Tab1Frag ment$1.onItemClick(Tab1Fragment.java:95) at android.widget.AdapterView.performItemClick(AdapterView.java:318) at android.widget.AbsListView.performItemClick(AbsListView.java:1165) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3134) at android.widget.AbsListView$3.run(AbsListView.java:4049) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Update: Station is now implementing Parcelable as well, as Naveen Dew suggested.

Station class-

public class Station implements Parcelable {
    String name;
    String description;
    String streamLink;
    int img;

    public Station(String name, String description, String streamLink, int img) {
        this.name = name;
        this.description = description;
        this.streamLink = streamLink;
        this.img = img;
    }

    protected Station(Parcel in) {
        name = in.readString();
        description = in.readString();
        streamLink = in.readString();
        img = in.readInt();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(description);
        dest.writeString(streamLink);
        dest.writeInt(img);
    }

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

    public static final Creator<Station> CREATOR = new Creator<Station>() {
        @Override
        public Station createFromParcel(Parcel in) {
            return new Station(in);
        }

        @Override
        public Station[] newArray(int size) {
            return new Station[size];
        }
    };

    String getStationName() {
        return name;
    }

    String getDescription() {
        return description;
    }

    String getStreamLink() {
        return streamLink;
    }

    int getStationImg() {
        return img;
    }

    void details() {
        System.out.println(name);
        System.out.println(description);
        System.out.println(streamLink);
        System.out.println(img);
        System.out.println("--------------");
    }
}

I'm facing a problem when passing the Library parcel to Service iv'e made for sound.

this is how i'm sending extra on intent to the the service -

                Intent serviceIntent = new Intent(getActivity(), BackgroundSoundService.class);
            serviceIntent.putExtra("Library", (Parcelable) mainLibrary);
            serviceIntent.putExtra("position", position);
            getContext().startService(serviceIntent);

here i'm trying to get the Library in the BackGroundSoundService -

    public int onStartCommand(Intent intent, int flags, int startId) {


    library = (Library) intent.getParcelableExtra("Library");
    position = intent.getIntExtra("position", 0);

}

Can not start the service!

Logcat -

java.lang.RuntimeException: Unable to start service com.tsuryohananov.israeliradio.BackgroundSoundService@823fbd with Intent { cmp=com.tsuryohananov.israeliradio/.BackgroundSoundService (has extras) }: java.lang.RuntimeException: Parcel android.os.Parcel@5f24b14: Unmarshalling unknown type code 7274617 at offset 10964 at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3556) at android.app.ActivityThread.-wrap20(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@5f24b14: Unmarshalling unknown type code 7274617 at offset 10964 at android.os.Parcel.readValue(Parcel.java:2754) at android.os.Parcel.readListInternal(Parcel.java:3103) at android.os.Parcel.readArrayList(Parcel.java:2305) at com.tsuryohananov.israeliradio.Library.(Library.java:64) at com.tsuryohananov.israeliradio.Library$1.createFromParcel(Library.java:103) at com.tsuryohananov.israeliradio.Library$1.createFromParcel(Library.java:100) at android.os.Parcel.readParcelable(Parcel.java:2781) at android.os.Parcel.readValue(Parcel.java:2675) at android.os.Parcel.readArrayMapInternal(Parcel.java:3042) at android.os.BaseBundle.unparcel(BaseBundle.java:257) at android.os.Bundle.getParcelable(Bundle.java:888) at com.tsuryohananov.israeliradio.BackgroundSoundService.onStartCommand(BackgroundSoundService.java:62) at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3539)

Update -

manifest -

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|screenSize"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!--
        <activity
        android:name=".NotificationView"
        android:configChanges="orientation|screenSize"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        </activity>
    -->


    <service
        android:name=".BackgroundSoundService"
        android:label="My Service">
    </service>

    <activity android:name=".PlayActivity"></activity>
</application>

your inner classes should also be Parcelable

check if Station is implementing Parcelable

UPDATE

Creator is missing from Library class

add this to your library class

public static final Creator<Library> CREATOR = new Creator<Library>() {
    @Override
    public Library createFromParcel(Parcel in) {
        return new Library(in);
    }

    @Override
    public Library[] newArray(int size) {
        return new Library[size];
    }
};

also please post your Manifest file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM