1

I am using Parcelable for a custom Song object I have in my class. However, when ever I am trying to get an arraylist extra of type Song I always get a null pointer exception. I have no problem getting string extras from the intent but when I try to get this ArrayList I need I always get null. I am also getting a null when I just try to pass a Song object, so I am assuming there is some issue with it but I cannot figure it out for the life of me.

This is my song class

import android.os.Parcel;
import android.os.Parcelable;
public class Song implements Parcelable {
    private String uri;
    private String title;
    private String artist;
    private String album;
    private String length;
    private int count;
    private int source;

    public Song () {

    }
    public Song (String title, String artist, String album, String uri, String length, int count,
                 int source) {
        this.uri = uri;
        this.title = title;
        this.artist = artist;
        this.album = album;
        this.length = length;
        this.count = count;
        this.source = source;
    }

    public String getUri() {
        return uri;
    }

    public String getArtist() {
        return artist;
    }

    public String getTitle() {
        return title;
    }

    public String getLength() {
        return length;
    }

    public int getCount() {return count;}
    @Override
    public String toString() {
        return title + " - " +artist;
    }

    @Override
    public boolean equals(Object o){
        if (o instanceof Song) {
            Song song = (Song) o;
            if (title.equals(song.title) && length.equals(song.length)) {
                return true;
            }
        }
        return false;
    }

    public int compareTo(Song s) {
        if (this.count < s.getCount()) {
            return -1;
        }
        else if(this.count > s.getCount()){
            return 1;
        }

        return 0;
    }


    public String getAlbum() {
        return album;
    }

    public void setAlbum(String album) {
        this.album = album;
    }

    public int getSource() {
        return source;
    }


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.uri);
        dest.writeString(this.title);
        dest.writeString(this.artist);
        dest.writeString(this.album);
        dest.writeString(this.length);
        dest.writeInt(this.count);
        dest.writeInt(this.source);
    }

    protected Song(Parcel in) {
        this.uri = in.readString();
        this.title = in.readString();
        this.artist = in.readString();
        this.album = in.readString();
        this.length = in.readString();
        this.count = in.readInt();
        this.source = in.readInt();
    }

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

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

This is the line I use to package the arraylist

Intent intent = new Intent();
        Log.d("UTILS ", " size: " +queue.size()); // Making sure it is not null before passing
        intent.setClass(context, PlayerService.class);
        intent.putParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST, queue);
        context.startService(intent);

This is retrieving the arraylist in PlayerService class

public static final String EXTRA_TRACK_LIST = "EXTRA_TRACK_LIST";
private ArrayList<Song> trackList;
    .
    .
    .


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

        if (intent == null || intent.getAction() == null) {
            Log.d(TAG, "unspecified command");
            return START_STICKY;
        }

        trackList=intent.getParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST);
        if (trackList == null) {
            Log.d("TRACKLIST", "IS NULL");
        } else {
            Log.d(TAG, "size: "+trackList.size());
        }
        .
        .
        .
        // more irrelevant code
osharifali
  • 31
  • 1
  • 5

2 Answers2

0

your parameter is wrong

public static final String EXTRA_TRACK_LIST = "EXTRA_TRACK_LIST";

so change like this

trackList = intent.getParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST);
sasikumar
  • 10,919
  • 2
  • 21
  • 42
  • I have tried both ways. This doesn't make a difference because the variable is defined in that class. – osharifali Aug 23 '16 at 05:30
  • @Override public int onStartCommand(Intent intent, int flags, int startId) { handleCommand(intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } – sasikumar Aug 23 '16 at 05:38
  • That is where I have put this code exactly. I have update my original post to show more information. – osharifali Aug 23 '16 at 05:41
0

Is queue a Queue/List or similar? Or is it an array? If array, should be queue.length, right? From List to array try this. This should work.

intent.putParcelableArrayListExtra(PlayerService.EXTRA_TRACK_LIST, queue);

If not, let me know to keep trying. Also, you could also pass it as String. You could use GSON to convert it to JSON string. After converted to String, pass it as a single String.

Intent intent = new Intent(ActivityA.this, Service.class);
intent.putExtra(new Gson().toJson(queue), PlayerService.EXTRA_TRACK_LIST);
context.startService(intent);

And to retrieve that object again:

Song song = new Gson().fromJson(intent.getStringExtra(PlayerService.EXTRA_TRACK_LIST), Song.class);

Or, if list (I believe you case):

Type listType = new TypeToken<ArrayList<Song.class>>(){}.getType();
List<Song> songList = new Gson().fromJson(intent.getStringExtra(PlayerService.EXTRA_TRACK_LIST), listType);
Community
  • 1
  • 1
Amg91
  • 132
  • 5
  • 22
  • It is an ArrayList which just happens to be named queue because it contains music from a song queue. I will try your Gson approach last, I believe there is an error in Parcelable implementation of my Song class. – osharifali Aug 23 '16 at 05:39