2013-08-05 10 views
20

Kann jemand einen ArrayList<NameValuePair> zu einem Intent als Extra hinzufügen?Absicht putExtra ArrayList <NameValuePair>

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); 

Hier ist die Klassendeklaration für RegisterActivity2:

public class RegisterActivity2 extends Activity implements Serializable { 
} 

Der Fehler in der logcat ist:

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

den Vorschlag von Ted Hopp, bekomme ich noch einen Fehler Nach der Implementierung. Hier ist der 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 

Antwort

20

Wie andere haben darauf hingewiesen, wenn Sie ein Array als Absicht extra geben wollen, müssen die Elemente Serializable implementieren. In Ihrem Fall ist der Ansatz ziemlich einfach (nicht ganz — siehe unten): Definieren Sie Ihre eigene Unterklasse von BasicNameValuePair und deklarieren Sie es, um die Schnittstelle zu implementieren.

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

Dann können Sie es verwenden, wie Sie versuchen, schon war:

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); 

Auf der Empfangsseite, müssen Sie ihn herausziehen mit:

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

EDIT Nun, das obige funktioniert nicht, da BasicNameValuePair keinen Standardkonstruktor hat und der Serialisierungsmechanismus nicht-serialisierbare Vorgängerklassen benötigt, um ein de zu haben Fehlerkonstruktor. Andernfalls erhalten Sie eine Ausnahme bei der Deserialisierung.

Leider bedeutet dies, dass die Lösung nicht so einfach ist, wie ich es ausgemacht habe. Ein Problem besteht darin, eine eigene Klasse zu definieren, die Parcelable, wie @keerthana murugesan suggests in his answer, implementiert. Wenn Sie zuvor Parcelable implementiert haben, wissen Sie, dass es ein bisschen schmerzt. Ein weiteres Werk-around ist eine Klasse zu definieren, die eine BasicNameValuePair Wraps (statt sich daraus ergebenden) und verwaltet seine eigene Serialisierung:

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 
    } 
} 
+0

Perfekt. Vielen Dank! – Alex

+0

@ usr55410 - Es war nicht ganz perfekt. Ich schlug vor, 'NameValuePair' zu bilden, was nicht funktionierte. Jetzt behoben. Ich nehme an, dass Sie diesen Teil selbst herausgefunden haben, da Sie dies bereits als Lösung akzeptiert haben. :) –

+0

Ja, habe ich. Es gibt jedoch noch ein Problem. Wenn ich das teste, erhalte ich eine Fehlermeldung "Parcelable hat IOException beim Lesen eines serialisierbaren Objekts gefunden". Meine NVP-Klasse implementiert Serializable. Irgendwelche Ideen? – Alex

0

Damit dies funktioniert, die genericized Typ Ihre Liste hält müssen Serializable implementieren.

+0

Vielen Dank. Ich habe die Klassendeklaration für die nächste Aktivität oben hinzugefügt. Ist es das, worauf du dich beziehst? Ich bekomme immer noch den gleichen Fehler. – Alex

+0

Nein, die Klasse, die Ihre Liste enthält, ist 'BasicNameValuePair', die 'Serializable' nicht implementiert. Das ist dein Problem. – Karakuri

1

Sie müssen ein Objekt-Array als Serializable in die Absicht übergeben. Das Objekt-Array muss aus Objekten bestehen, die wiederum serialisierbar sind.

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)); 

Hier muss BaseNameValuePair eine Klasse sein, die Serializable implementiert. Verwenden Sie toArray von ArrayList in Put und typecast es zu Serializable. Verwenden Sie in Ihrer Getter-Aktivität Methode auf die Absicht.

0

Dies kann über die Schnittstelle Parcelable erreicht werden.

  1. Machen Sie Ihre BasicNameValuePair Klasse Parcelable interface.see this für mehr Bezug zu implementieren.

    public class BasicNameValuePair implements Parcelable{ 
    
    } 
    
  2. diese Objekte zu einem ArrayList hinzufügen, wie Sie oben haben,

    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)); 
    
  3. Pass diese in intentputParcelableArrayListExtra() verwenden.

    intent.putParcelableArrayListExtra ("nvp", nameValuePairs); 
    startActivity(intent); 
    
13

Ich hatte das gleiche Problem und versucht, Objekte in Arraylist zu senden, ohne Seiralizable in Objekt Umsetzung Klasse.

Die Shortcut-Lösung bestand darin, ArrayList in Bundle einzubetten.

also in der ersten Aktivität ->

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); 

Zweite Aktivität ->

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

funktioniert.

+0

Warum ist das nicht die richtige Antwort? Es ist einfach und einfach – Zen

+0

Ich benutze dies. Aber gibt es einen Nachteil, den Sie erlebt haben oder irgendwelche Vorteile oder die Implementierung von Seiralizable? – Zen

+0

Das stürzt ab! Kann ArrayList nicht marschieren. .. – Zen

Verwandte Themen