0

I have to send an ArrayList of BasicNameValuePairs to another Activity in my Android app. First it did not allow me to do this, saying BasicNameValuePair is not serializable.

So after reading a few other answers, I followed their recommendations made my own class called SerializedNameValuePair which implements serializable, and thought of passing an ArrayList of this.

public class SerializedNameValuePair implements Serializable, NameValuePair{

    private BasicNameValuePair nvp;

    public SerializedNameValuePair(String name, String value){
        nvp=new BasicNameValuePair(name, value);

    }

     @Override
        public String getName() {
            return nvp.getName();
        }

        @Override
        public String getValue() {
            return nvp.getValue();
        }

        // serialization support

        private static final long serialVersionUID = 1L;

        private void writeObject(ObjectOutputStream out) throws IOException {
            out.writeChars(nvp.getName());
            out.writeChars(nvp.getValue());
        }

        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            nvp = new BasicNameValuePair(in.readUTF(), in.readUTF());
        }

        @SuppressWarnings("unused")
        private void readObjectNoData() throws ObjectStreamException {
            // nothing to do
        }

}

Then i make an ArrayList of this and try passing it in an Intent.

places is declared as a variable of ShipmentFindingActivity itself.

ArrayList <SerializedNameValuePair>places;

In the postExecute of an AsyncTask I initialize it.

places=new ArrayList<SerializedNameValuePair>();

Then I populate the ArrayList in a for loop.

SerializedNameValuePair nvp=new SerializedNameValuePair(eventname, placename);
places.add(nvp);

There is a button that has it's visibility set to invisible first. After the postExecute executes, it becomes visible and it's onClick is openMap.

public void openMap(View view){
    System.out.println("Map View Button Pressed");

    Intent intent=new Intent(context, MapViewingActivity.class);
    intent.putExtra("places", places);
    startActivity(intent);
}

Here the app crashes when i click on the button. I am receiving the intent in MapViewingActivity like this:

Intent intent=getIntent();
nameValuePairs=(ArrayList<SerializedNameValuePair>) intent.getSerializableExtra("nvp");

When the app crashes this is what I get in LogCat:

06-04 06:39:13.546: E/AndroidRuntime(2733): FATAL EXCEPTION: main
06-04 06:39:13.546: E/AndroidRuntime(2733): Process: com.example.tradeapp, PID: 2733
06-04 06:39:13.546: E/AndroidRuntime(2733): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tradeapp/com.example.tradeapp.MapViewingActivity}: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.tradeapp.SerializedNameValuePair)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Handler.dispatchMessage(Handler.java:102)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Looper.loop(Looper.java:136)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread.main(ActivityThread.java:5017)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.lang.reflect.Method.invokeNative(Native Method)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.lang.reflect.Method.invoke(Method.java:515)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at dalvik.system.NativeStart.main(Native Method)
06-04 06:39:13.546: E/AndroidRuntime(2733): Caused by: java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object (name = com.example.tradeapp.SerializedNameValuePair)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readSerializable(Parcel.java:2215)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readValue(Parcel.java:2064)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readListInternal(Parcel.java:2343)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readArrayList(Parcel.java:1703)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readValue(Parcel.java:2034)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readArrayMapInternal(Parcel.java:2314)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Bundle.unparcel(Bundle.java:249)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Bundle.getSerializable(Bundle.java:1295)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.content.Intent.getSerializableExtra(Intent.java:4694)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at com.example.tradeapp.MapViewingActivity.onCreate(MapViewingActivity.java:38)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.Activity.performCreate(Activity.java:5231)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
06-04 06:39:13.546: E/AndroidRuntime(2733):     ... 11 more
06-04 06:39:13.546: E/AndroidRuntime(2733): Caused by: java.io.EOFException
06-04 06:39:13.546: E/AndroidRuntime(2733):     at libcore.io.Streams.readFully(Streams.java:83)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.DataInputStream.readFully(DataInputStream.java:99)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.DataInputStream.decodeUTF(DataInputStream.java:178)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.DataInputStream.decodeUTF(DataInputStream.java:173)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.DataInputStream.readUTF(DataInputStream.java:169)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:2113)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at com.example.tradeapp.SerializedNameValuePair.readObject(SerializedNameValuePair.java:41)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.lang.reflect.Method.invokeNative(Native Method)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.lang.reflect.Method.invoke(Method.java:515)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1332)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1244)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1833)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:762)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1981)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1938)
06-04 06:39:13.546: E/AndroidRuntime(2733):     at android.os.Parcel.readSerializable(Parcel.java:2213)
06-04 06:39:13.546: E/AndroidRuntime(2733):     ... 23 more

Any ideas how to fix?

Kartik_Koro
  • 1,277
  • 1
  • 11
  • 23
  • You can try Parcelable – Top Cat Jun 04 '14 at 10:45
  • @Lollipop Well I have no idea what that is, I'll look it up and try it out. – Kartik_Koro Jun 04 '14 at 10:46
  • You are passing using key `places` but retrieving using `nvp`. Why? – Apoorv Jun 04 '14 at 10:54
  • @kartik look this http://derekknox.com/daklab/2012/09/05/quick-tip-android-parcelable-example-with-arraylist/ Parcellable is faster than serializable Ref this http://www.developerphil.com/parcelable-vs-serializable/ – Top Cat Jun 04 '14 at 10:54
  • @Lollipop umm... I've implemented parcelable and added all the required methods into a class called ParcelableNVParray. Following derekknox's quide, the class has a constructor that takes in a Parcel to initialize the data. How do i store my ArrayList into this Parcel now?? – Kartik_Koro Jun 04 '14 at 11:31

2 Answers2

1

It turns out that since the class BasicNameValuePair itself is not Serializable, putting it in another class that is Serializable or Parcelable or anything of that sort leads to the same error, I tried making a class SerializedNameValuePair that implemented Serializable and had a BasicNameValuePair, then made an ArrayList of SerializedNameValuePair, then stored that ArrayList in an object whose class implemented Parcelable. Still no result, it all came down to BasicNameValuePair is not Serializable. So why use BasicNameValuePair at all? I just made a simple class called StringPair that implemented Serializable and then I was easily able to pass the ArrayList of StringPair in an Intent. This seems like the simplest, cleanest method to me.

Here is my class:

public class StringPair implements Serializable{

    private static final long serialVersionUID = 1L;
    public String first;
    public String second;
    public StringPair(String first, String second){
        this.first=first;
        this.second=second;
    }

}

And I send an Intent like this:

Intent intent=new Intent(context, MapViewingActivity.class);
intent.putExtra("places", (Serializable)places);
startActivity(intent);

Where places is:

ArrayList<StringPair>places=new ArrayList<StringPair>();

I receive the Intent again like this:

Intent intent=getIntent();
ArrayList<StringPair >nameValuePairs=(ArrayList<StringPair >)intent.getSerializableExtra("places");

This code worked perfectly for me and it's extremely simple.

Some may argue that Parcelable is alot faster than Serializable, but according to the benchmarks provided in http://www.developerphil.com/parcelable-vs-serializable/ , there is a difference of few miliseconds between the two when the contents of the bundle are read/written 1000 times. In my app I know that my ArrayList will not contain more than 10 elements so I went ahead with Serializable knowing it would not make a difference in speed, and will reduce complexity.

Kartik_Koro
  • 1,277
  • 1
  • 11
  • 23
0

you need to create a customClass that implement Parcebale, you can see this issue it work fine Create intent with parcebale

Community
  • 1
  • 1
wSakly
  • 387
  • 1
  • 10