parcelable encountered ioexception writing serializable object.........?
Asked Answered
S

5

6

The code

SngList.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView a, View v, int position, long id) {


        Intent intent = new Intent(getActivity(), NowPlaying.class);
        intent.putExtra("Data1",Songinfo);
        intent.putExtra("Data2",position);
        startActivity(intent);

    }
});

code in the receiving class

Intent i = getIntent();
ArrayList<SongDetails> Songinfo2 = (ArrayList<SongDetails>)i.getSerializableExtra("Data1"); 
position=i.getIntExtra("Data2", 1);

code for songDetials

package sourcecode.jazzplayer;

import java.io.Serializable;

import android.graphics.Bitmap;

public class SongDetails implements Serializable{
    Bitmap icon ;
    String song;
    String Artist; 
    String Album;
    String Path;
   int icLauncher;

    public String getSong() {
        return song;
    }

    public void setSong(String song) {
        this.song = song;
    }

    public String getArtist() {
        return Artist;
    }

    public void setArtist(String Artist) {
        this.Artist = Artist;
    }

    public Bitmap getIcon() {
        return icon;
    }

    public void setIcon(Bitmap bitmap) {
        this.icon = bitmap;
    }

    public String getPath2() {
        return Path;
    }

    public void setPath2(String Path) {
        this.Path = Path;
    }

    public String getAlbum() {
        return Album;
    }

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

    public void setIcon(int icLauncher) {
        this.icLauncher = icLauncher;
    }
}

the whole code:

public class FragmentSongs extends  Fragment implements Serializable {
    AdapterView.AdapterContextMenuInfo info;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {

        View view = inflater.inflate(R.layout.fragment_song, container, false);
        ListView SngList = (ListView) view.findViewById(R.id.SongList);
        registerForContextMenu(SngList);
        File f=new File("/system/");
        //File f=new File("/sdcard/Music");
        int j=0;int i=0;



         final ArrayList<SongDetails> Songinfo = getSongsFromDirectory(f);

        if (Songinfo.size()>0)
        {

            for( j=0; j<Songinfo.size();j++)
            {
                for ( i=j+1 ; i<Songinfo.size(); i++)
                { 
                    SongDetails a=Songinfo.get(i);
                    SongDetails b=Songinfo.get(j);
                    if(a.getSong().toLowerCase().compareTo(b.getSong().toLowerCase())<0)
                    {   

                        Songinfo.set(i,b );
                        Songinfo.set(j,a);
                    }
                }

            }

            SngList.setOnItemClickListener(new OnItemClickListener() {
                 public void onItemClick(AdapterView a, View v, int position, long id) {


                       Intent intent = new Intent(getActivity(), NowPlaying.class);
                       intent.putExtra("Data1",Songinfo);
                       intent.putExtra("Data2",position);
                       startActivity(intent);

                             }
                     });

           SngList.setAdapter(new CustomAdapter(Songinfo));
           return view;
        }
        else return null;

    }



        public ArrayList<SongDetails> getSongsFromDirectory(File f)
        {MediaMetadataRetriever mmr = new MediaMetadataRetriever();
            ArrayList<SongDetails> songs = new ArrayList<SongDetails>();
            Bitmap bitmap2; 
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ab);

            float ht_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());
            float wt_px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());

            bitmap2 = Bitmap.createScaledBitmap(bmp, (int) ht_px, (int) wt_px, true);



           byte[] rawArt = null;
            Bitmap art;
            BitmapFactory.Options bfo=new BitmapFactory.Options();
            if (!f.exists() || !f.isDirectory()) 

            {    
                return songs;
            }
            File[] files = f.listFiles(new Mp3Filter());
            for(int i=0; i<files.length; i++) 
            { 

                if (files[i].isFile())
                { 


                 //mmr.setDataSource(files[i].getPath());
                // rawArt = mmr.getEmbeddedPicture();
                    SongDetails detail=new SongDetails(); 
                //if ( rawArt != null) 

                //{ 
                    //bitmap2=BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
                    //bitmap2 = Bitmap.createScaledBitmap(bitmap2, (int) ht_px, (int) wt_px, true);

                    //detail.setIcon(bitmap2);
                //}//else 
            //{     
                    detail.setIcon(bitmap2);
                //} 

                    detail.setSong(files[i].getName()); 
          // detail.setArtist(files[i].getName());
          // detail.setAlbum(files[i].getName());

             //detail.setArtist(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)); 

          // detail.setAlbum(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)); 
           detail.setPath2( files[i].getPath()) ;
           songs.add(detail); 
                }
                else if (files[i].isDirectory())
                { 
                songs.addAll(getSongsFromDirectory(files[i])); 
                } 

            }       return songs;
    }
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
        {
                        super.onCreateContextMenu(menu, v, menuInfo);      
                       info = (AdapterContextMenuInfo) menuInfo;
                       menu.add(Menu.NONE, v.getId(), 0, "Play");
                       menu.add(Menu.NONE, v.getId(), 0, "Delete");
                       menu.add(Menu.NONE, v.getId(), 0, "Queue Item");                  
               }

        @Override
        public boolean onContextItemSelected(MenuItem item) {
                if (item.getTitle() == "Play") {

                       }
                 else if (item.getTitle() == "Delete") {

                       }

                 else if (item.getTitle() == "Queue Item") {

                       }
                 else     {
                       return false;
                       }
               return true;
               }}


        class Mp3Filter implements FileFilter
        {
            public boolean accept(File file)
            {
            return (file.isDirectory()||file.getName().endsWith(".apk")|| file.getName().endsWith(".Mp3"));
            }
        }

The Log

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = sourcecode.jazzplayer.SongDetails)

Shostakovich answered 9/8, 2013 at 13:27 Comment(12)
The problem is caused by: java.io.NotSerializableException: Is your class Songinfo2 serializable?Lewanna
well songinfo is an object of songdetails class and i have implemented serializable on itShostakovich
can you post your class SongInfo?Lewanna
i am sorry for using capital "S" in songinfo...as i said.its not a class..if you meant SongDetails...i have updated my question and provided you with the codeShostakovich
please post your code properly. then only we can find what is your problem!!!Rivet
final ArrayList<SongDetails> Songinfo = getSongsFromDirectory(f);Shostakovich
please post your activity fully.Rivet
@Rivet yeah sorry but had Songinfo been a string i would not have used Serializable.....because Serializable is used for objects of classes that you have created and not inbuilt classes(or data type its commonly said)Shostakovich
@Rivet posted the whole codeShostakovich
Well yes you may say........i am able to generate the list in a custom adapter but the problem arises when i click on it..i want to play the song in another activity.....and i am unable to pass Songinfo(the object)....i am able to pass any other object of inbuilt data types..like int and string and all....but not the object of this class.....Shostakovich
@Rivet ..got any idea what i should doShostakovich
@mirco.widmer got any idea what i should do ?Shostakovich
L
9

Ok i implemented part of it for you. You have to add all the other properties of your SongDetails class:

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SongDetails Songinfo1 = new SongDetails();
    Songinfo1.setSong("song1");

    SongDetails Songinfo2 = new SongDetails();
    Songinfo2.setSong("song2");

    ArrayList<SongDetails> list = new ArrayList<SongDetails>();
    list.add(Songinfo1);
    list.add(Songinfo2);

    Intent intent = new Intent(this, SecondActivity.class);
    intent.putParcelableArrayListExtra("Data1", list);
    intent.putExtra("Data2", 1);
    startActivity(intent);

}

In the activity in which you are retrieving the songs, use this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_asdf);

    ArrayList<SongDetails> songs = getIntent().getParcelableArrayListExtra("Data1");

    for(SongDetails songDetails : songs) {
        Log.i("", songDetails.getSong());
    }
}

Your SongDetails class should look like this:

SongDetails:

public class SongDetails implements Parcelable {
    Bitmap icon;
    String song;
    String Artist;
    String Album;
    String Path;
    int icLauncher;

    public SongDetails() {
    }

    public SongDetails(Parcel in) {
        String[] data = new String[1];
        in.readStringArray(data);
        this.song = data[0];
    }

    public String getSong() {
        return song;
    }

    public void setSong(String song) {
        this.song = song;
    }

    public String getArtist() {
        return Artist;
    }

    public void setArtist(String Artist) {
        this.Artist = Artist;
    }

    public Bitmap getIcon() {
        return icon;
    }

    public void setIcon(Bitmap bitmap) {
        this.icon = bitmap;
    }

    public String getPath2() {
        return Path;
    }

    public void setPath2(String Path) {
        this.Path = Path;
    }

    public String getAlbum() {
        return Album;
    }

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

    public void setIcon(int icLauncher) {
        this.icLauncher = icLauncher;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringArray(new String[] { this.song });
    }

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

        public SongDetails[] newArray(int size) {
            return new SongDetails[size];
        }
    };
}
Lewanna answered 9/8, 2013 at 14:47 Comment(12)
should the receiving and the class which is passing still implement serializable or parceleableShostakovich
when i write this line intent.putParcelableArrayListExtra("Data1", list); it says cast argument of list to ArrayList<?Extends Parceable>Shostakovich
is your class SongDetails defined as following: public class SongDetails implements Parcelable { … } ?Lewanna
i casted that and it crashed againShostakovich
you don't have to cast anything. i uploaded my example again (with multiple songs), take a look and ask if you don't get parts of it: dropbox.com/s/4iqbwf5fv9fq413/Test.zipLewanna
did you run it? if yes: did it print out song1 and song2 in the adb?Lewanna
It did print out "song1" and "song2" into the logcat of eclipse. That's the corresponding code: for(SongDetails songDetails : songs) { Log.i("", songDetails.getSong()); }Lewanna
well i can't see anything in the log....so i edited the code so that it prints it in the textview.......and yes it displays it...Shostakovich
so, that should show you how you can pass along two songs to the next intent. did this solve your question?Lewanna
yeah the app is not crashing anymore...thanx to you..i will have to edit it to use it for my own purposeShostakovich
for(SongDetails songDetails : songs) { Log.i("", songDetails.getSong()); this code works fine...but when i use ...it doesn't work...so i am still stuck Log.i("", songs.get(0).getSong());Shostakovich
you probably better use ArrayList<SongDetails> songs = getIntent().getParcelableArrayListExtra("Data1"); in your receiving class.Lewanna
X
0

According to https://forums.bignerdranch.com/t/challenge-saving-state-notserializableexception-error/8018/5 you should implement or extend some class from Parcelable. In my case I had a DialogFragment with an interface MyCallback extending Serializable. In newInstance(MyCallback callback) builder I used:

Bundle args = new Bundle();
args.putSerializable(key, callback);

that led to an exception. Then I rewrote MyCallback to extend Parcelable and also added some methods to a callback when invoked this DialogFragment. At least, it doesn't crash on Home button or screen off.

Also changed to:

Bundle args = new Bundle();
args.putParcelable(key, callback);
Xhosa answered 9/9, 2016 at 11:20 Comment(4)
could you share how you do "MyCallback to extend Parcelable"? also, did you tried a callback that deals with context, livedata?Luau
@MahmoudMabrok, it's a good question. I forgot what had done. Probably passed data like data class MyCallback(data: SomeClass, callback: (Context) -> Unit): Parcelable. Here data class SomeClass(...): Parcelable and callback is not parcelable. Currently I don't use LiveData, only StateFlow, but don't use this solution at all. You are right, it would be better to use setFragmentResultListener, I suppose.Xhosa
the issue here, that we need to do action/callback while dialog is opened.Luau
@MahmoudMabrok, I think, you should ask a new question. If we cannot pass a method to Dialog, we can create a class (interface) with needed methods and pass it there. Then in Dialog create an instance of that class and make work.Xhosa
L
0

I know where the problem is in your case and that is about the BitMap All you need to do is Decode your BitMap before sending into intent

Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.thumbsup);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        largeIcon.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] byteArray = stream.toByteArray();

And then send the following Object in intent

intent.putExtras("remindermessage",object);

and if not about the Bitmap then you should look for other things which might be taking more space and decode them before sending into intent

Leprechaun answered 25/8, 2017 at 11:58 Comment(0)
H
0

In my case, there was a nested Delivery class inside the actual class Order (implements Serializable) which was not serialized, once Delivery class also implemented Serializable, the exception is gone. I didn't have to implement parcelable at all. Hope this helps someone!

Heifetz answered 21/5, 2020 at 15:19 Comment(0)
R
-1

To get the arraylist from another activity.

      ArrayList<SongDetails> list = new ArrayList<SongDetails>();
              list=  getIntent().getStringArrayListExtra("Data1");

To pass the arraylist to another activity.

intent.putStringArrayListExtra("Data1", Songinfo);

To split the array list:

        for(SongDetails name: list)
        {
        String yoursong= name.song;
        }

Hope this will give you some solution.

Rivet answered 9/8, 2013 at 13:41 Comment(5)
.getStringArrayListExtra( and here the code is to fetch stringShostakovich
no it didn't work....and how can it??Songinfo is not a string its an object of SongDetails ,a class that i have createdShostakovich
@AnkitSrivastava what is Songinfo? means how did u declare this?where did you declare?Rivet
final ArrayList<SongDetails> Songinfo = getSongsFromDirectory(f);Shostakovich
i have tried it already.....the code gets marked with red line and one of the auto correct option says"change type of Songinfo to ArrayList<String>Shostakovich

© 2022 - 2024 — McMap. All rights reserved.