web-dev-qa-db-fra.com

Intention putExtra ArrayList <NameValuePair>

Est-ce que quelqu'un sait comment ajouter un ArrayList<NameValuePair> à une intention en plus?

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

Voici la déclaration de classe pour RegisterActivity2:

public class RegisterActivity2 extends Activity implements Serializable {
}

L'erreur dans le logcat est:

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

Après avoir mis en œuvre la suggestion de Ted Hopp, une erreur persiste. Voici la trace de la pile:

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
25
Alex

Comme d'autres l'ont noté, lorsque vous souhaitez passer un tableau en tant qu'intention supplémentaire, les éléments doivent implémenter Serializable. Dans votre cas, l'approche est assez simple (pas tout à fait - voir ci-dessous): définissez votre propre sous-classe de BasicNameValuePair et déclarez-la pour implémenter l'interface.

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

Ensuite, vous pouvez l’utiliser comme vous l’avez essayé:

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

Sur le destinataire, vous devrez le sortir avec:

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

EDIT Eh bien, ce qui précède ne fonctionnera pas car BasicNameValuePair n'a pas de constructeur par défaut et le mécanisme de sérialisation nécessite que les classes ancêtres non sérialisables aient un constructeur par défaut. Sinon, vous obtiendrez une exception lors de la désérialisation.

Malheureusement, cela signifie que la solution n'est pas aussi simple que ce que j'ai imaginé. Une solution consiste à définir votre propre classe pour implémenter Parcelable, comme le suggère @keerthana murugesan dans sa réponse . Si vous avez déjà implémenté Parcelable, vous savez que c'est un peu pénible. Une autre solution consiste à définir une classe qui enveloppe une BasicNameValuePair (au lieu de dériver de celle-ci) et gère sa propre sérialisation:

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
    }
}
24
Ted Hopp

J'ai eu le même problème, en essayant d'envoyer des objets dans ArrayList sans implémenter Seiralizable dans la classe Object.

La solution de raccourci consistait à envelopper ArrayList dans Bundle.

Donc, dans la première activité ->

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

Deuxième activité ->

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

Fonctionne bien.

19
Ogmi

Vous devez passer un tableau d'objets en tant que Serializable dans l'intention. Le tableau d'objets doit être composé d'objets sérialisables à l'intérieur.

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

Ici, BaseNameValuePair doit être une classe qui implémente Serializable. Utilisez toArray of ArrayList dans put et typecast it à Serializable. Dans votre activité de lecture, utilisez la méthode getSerializable sur l'intention.

1
taxeeta

Ceci peut être réalisé en utilisant l'interface Parcelable.

  1. Faites en sorte que votre classe BasicNameValuePair implémente Parcelable interface.see this pour plus de références.

    public class BasicNameValuePair implements Parcelable{
    
    }
    
  2. Ajoutez ces objets à une ArrayList comme ci-dessus,

    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. Transmettez-les dans intent en utilisant putParcelableArrayListExtra().

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

Pour que cela fonctionne, le type générique de votre liste doit implémenter Serializable.

0
Karakuri