0
votes

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.Tab1Fragment$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>

1
Use Gson. My life is easier now. - None
you have an example? - Tsur Yohananov
Did it, now I'm getting this error: - Tsur Yohananov
java.lang.ClassNotFoundException: com.tsuryohananov.israeliradio.Station for the line: stations = in.readArrayList(null); - Tsur Yohananov

1 Answers

0
votes

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