Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intent putExtra ArrayList<NameValuePair>

Does anyone know how to add an ArrayList<NameValuePair> to an Intent as an extra?

ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("first_name", first_name)); nameValuePairs.add(new BasicNameValuePair("last_name", last_name)); nameValuePairs.add(new BasicNameValuePair("email", email)); nameValuePairs.add(new BasicNameValuePair("password", password));  /* Move on to step 2 */ Intent intent = new Intent(RegisterActivity1.this, RegisterActivity2.class); intent.putExtra("nvp", nameValuePairs); startActivity(intent); 

Here is the class declaration for RegisterActivity2:

public class RegisterActivity2 extends Activity implements Serializable { } 

The error in the logcat is:

> Parcel: unable to marshal value first_name="whatever" 

After implementing the suggestion by Ted Hopp, I still get an error. Here is the stack trace:

08-04 22:10:16.095: E/AndroidRuntime(5065): FATAL EXCEPTION: main > 08-04 22:10:16.095: E/AndroidRuntime(5065): > java.lang.RuntimeException: Unable to start activity > ComponentInfo{/.RegisterActivity2}: java.lang.RuntimeException: > Parcelable encountered IOException reading a Serializable object (name > = database.NVP) 08-04 22:10:16.095: E/AndroidRuntime(5065):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2070) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2095) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > android.app.ActivityThread.access$600(ActivityThread.java:135) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > android.os.Handler.dispatchMessage(Handler.java:99) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.os.Looper.loop(Looper.java:137) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > android.app.ActivityThread.main(ActivityThread.java:4849) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > java.lang.reflect.Method.invokeNative(Native Method) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > java.lang.reflect.Method.invoke(Method.java:511) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > dalvik.system.NativeStart.main(Native Method) 08-04 22:10:16.095: > E/AndroidRuntime(5065): Caused by: java.lang.RuntimeException: > Parcelable encountered IOException reading a Serializable object (name > = database.NVP) 08-04 22:10:16.095: E/AndroidRuntime(5065):   at android.os.Parcel.readSerializable(Parcel.java:2144) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.os.Parcel.readValue(Parcel.java:2016) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > android.os.Parcel.readListInternal(Parcel.java:2235) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.os.Parcel.readArrayList(Parcel.java:1655) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > android.os.Parcel.readValue(Parcel.java:1986) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > android.os.Parcel.readMapInternal(Parcel.java:2226) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.os.Bundle.unparcel(Bundle.java:223) 08-04 22:10:16.095: > E/AndroidRuntime(5065):   at > android.os.Bundle.getSerializable(Bundle.java:1254) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.content.Intent.getSerializableExtra(Intent.java:4268) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > .RegisterActivity2.onCreate(RegisterActivity2.java:24) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.app.Activity.performCreate(Activity.java:5244) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     at > android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1082) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2034) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   ... 11 more 08-04 > 22:10:16.095: E/AndroidRuntime(5065): Caused by: > java.io.InvalidClassException: > org.apache.http.message.BasicNameValuePair; IllegalAccessException > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectStreamClass.resolveConstructorClass(ObjectStreamClass.java:694) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:655) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1816) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectInputStream.readObject(ObjectInputStream.java:2003) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > java.io.ObjectInputStream.readObject(ObjectInputStream.java:1960) > 08-04 22:10:16.095: E/AndroidRuntime(5065):   at > android.os.Parcel.readSerializable(Parcel.java:2142) 08-04 > 22:10:16.095: E/AndroidRuntime(5065):     ... 23 more 
like image 506
AndroidDev Avatar asked Aug 05 '13 03:08

AndroidDev


People also ask

What is the putExtra () method used with intent for?

Using putExtra() We can start adding data into the Intent object, we use the method defined in the Intent class putExtra() or putExtras() to store certain data as a key value pair or Bundle data object. These key-value pairs are known as Extras in the sense we are talking about Intents.

What is intent putExtra?

Intents are asynchronous messages which allow Android components to request functionality from other components of the Android system. For example an Activity can send an Intents to the Android system which starts another Activity . putExtra() adds extended data to the intent.

How can I get intent data from another activity?

For sending the value we will use intent. putExtra("key", Value); and during receive intent on another activity we will use intent. getStringExtra("key"); to get the intent data as String or use some other available method to get other types of data ( Integer , Boolean , etc.).


2 Answers

As others have noted, when you want to pass an array as an intent extra, the elements need to implement Serializable. In your case, the approach is fairly simple (not quite — see below): define your own subclass of BasicNameValuePair and declare it to implement the interface.

public class NVP extends BasicNameValuePair implements Serializable {     public NVP(String name, String value) {         super(name, value);     } } 

Then you can use it like you've been trying:

ArrayList<NVP> nameValuePairs = new ArrayList<NVP>(); nameValuePairs.add(new NVP("first_name", first_name)); nameValuePairs.add(new NVP("last_name", last_name)); nameValuePairs.add(new NVP("email", email)); nameValuePairs.add(new NVP("password", password));  /* Move on to step 2 */ Intent intent = new Intent(RegisterActivity1.this, RegisterActivity2.class); intent.putExtra("nvp", nameValuePairs); startActivity(intent); 

On the receiving end, you'll need to pull it out with:

ArrayList<NVP> nameValuePairs = (ArrayList<NVP>) intent.getSerializable("nvp"); 

EDIT Well, the above won't work because BasicNameValuePair doesn't have a default constructor and the serialization mechanism requires non-serializable ancestor classes to have a default constructor. Otherwise you'll get an exception on deserialization.

Unfortunately, this means that the solution isn't as simple as I made out. One work-around is to define your own class to implement Parcelable, as @keerthana murugesan suggests in his answer. If you've implemented Parcelable before, you know it's a bit of a pain. Another work-around is to define a class that wraps a BasicNameValuePair (instead of deriving from it) and manages its own serialization:

public class NVP implements NameValuePair, Serializable {     private BasicNameValuePair nvp;      public NVP(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.writeString(nvp.getName());         out.writeString(nvp.getValue());     }      private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {         nvp = new BasicNameValuePair(in.readString(), in.readString());     }      private void readObjectNoData() throws ObjectStreamException {         // nothing to do     } } 
like image 56
Ted Hopp Avatar answered Oct 22 '22 03:10

Ted Hopp


I had the same problem, trying to send objects in ArrayList without implementing Seiralizable in Object class.

The shortcut solution was to envelop ArrayList in Bundle.

So, in the first activity ->

ArrayList<Object> objects = new ArrayList<Object>();  // Object class does not implement Serializable interface  Bundle extra = new Bundle(); extra.putSerializable("objects", objects);  Intent intent = new Intent(getBaseContext(), ShowSpread.class); intent.putExtra("extra", extra); 

Second activity ->

Bundle extra = getIntent().getBundleExtra("extra"); ArrayList<Object> objects = (ArrayList<Object>) extra.getSerializable("objects") 

Works fine.

like image 24
Ogmi Avatar answered Oct 22 '22 03:10

Ogmi