2013-08-05 3 views
20

Кто-нибудь знает, как добавить ArrayList<NameValuePair> в намерение в качестве дополнительного?Intent 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); 

Вот класс декларация RegisterActivity2:

public class RegisterActivity2 extends Activity implements Serializable { 
} 

Ошибка в LogCat является:

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

После реализации предложения Тэда Hopp, я все еще получаю ошибку. Вот трассировки стека:

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 

ответ

20

Как уже отмечалось, когда вы хотите передать массив как намерение дополнительные элементы необходимо реализовать Serializable. В вашем случае подход довольно прост (не совсем — см. Ниже): определите свой собственный подкласс BasicNameValuePair и объявите его для реализации интерфейса.

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

Затем вы можете использовать его, как вы пытались:

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

На приемном конце, вы должны вытащить его с:

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

EDIT Ну, вышесказанное не будет работать, потому что BasicNameValuePair не имеет конструктора по умолчанию, и механизм сериализации требует, чтобы классы, не связанные с сериализацией, конструктор ошибок. В противном случае вы получите исключение при десериализации.

К сожалению, это означает, что решение не так просто, как я выяснил. Одной рабочей задачей является определение вашего собственного класса для реализации Parcelable, как @keerthana murugesan suggests in his answer. Если вы уже внедрили Parcelable, вы знаете, что это немного боль. Другая работа вокруг, чтобы определить класс, который оборачивает в BasicNameValuePair (вместо получения от него) и управляет своей собственной сериализации:

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

Отлично. Благодаря! – Alex

+0

@ usr55410 - Это было не совсем идеально. Я предложил подкласс «NameValuePair», который не собирался работать. Исправлено. Я предполагаю, что вы сами поняли эту часть, поскольку вы уже приняли это решение. :) –

+0

Да, я сделал. Однако есть еще одна проблема. Когда я тестирую это, я получаю сообщение об ошибке «Parcelable столкнулся с IOException, читающим сериализуемый объект». Мой класс NVP реализует Serializable. Есть идеи? – Alex

0

Для этого на работу, обобщенного типа ваш список держит необходимо реализовать Serializable.

+0

спасибо. Я добавил объявление класса для следующего действия выше. Это то, о чем вы говорите? Я все равно получаю ту же ошибку. – Alex

+0

Нет, класс, который принадлежит вашему списку, это 'BasicNameValuePair', который не реализует' Serializable'. Это твоя проблема. – Karakuri

1

Вам необходимо передать массив объектов в качестве Serializable в намерение. Массив объекта должен состоять из объектов, которые являются inturn Serializable.

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

Здесь BaseNameValuePair должен быть класс, который реализует Serializable. Использовать toArray от ArrayList в комплект, а тип до Serializable. В вашем методе Getter используйте метод getSerializable с намерением.

0

Этого можно достичь с помощью интерфейса Parcelable.

  1. Сделайте свой BasicNameValuePair класс для реализации Parcelablethis interface.see для получения дополнительной справки.

    public class BasicNameValuePair implements Parcelable{ 
    
    } 
    
  2. Добавьте эти объекты к ArrayList, как вы делали выше,

    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. Передайте их в intent используя putParcelableArrayListExtra().

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

Я была такая же проблема, пытаясь отправить объекты в ArrayList без реализации Seiralizable в объекте класс.

Ярлык для конвертирования ArrayList в Bundle.

Таким образом, в первой деятельности ->

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

Второе направление деятельности ->

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

работает отлично.

+0

Почему это не правильный ответ? Его простой и легкий – Zen

+0

Im, используя это. Но есть ли какой-либо недостаток, с которым вы столкнулись, или какие-либо преимущества или реализация Seiralizable? – Zen

+0

Это сбой! Не удалось маршель ArrayList . .. – Zen

Смежные вопросы