将一个对象的ArrayList传递给新的Activity

29

我有一个对象的ArrayList,如下所示:ArrayList<ObjectName>

我想将它传递到一个新的Activity中。 我尝试使用putParcelableArrayList,但它对对象存在问题。 我从变量创建中删除了<ObjectName>部分,这种方法可以工作,但是然后我得到了Eclipse complaining about unsafe stuff的错误。

如何将这个ArrayList<ObjectName>传递到新的Activity中?

感谢您的时间。

编辑

ArrayList<ObjectName> arraylist = new Arraylist<ObjectName>();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("arraylist", arraylist);

我遇到了以下错误:

The method `putParcelableArrayList(String, ArrayList<? extends Parcelable>)` in the type `Bundle` is not applicable for the arguments `(String, ArrayList<ObjectName>)`

编辑2 对象示例代码。我需要更改它才能使Parcelable工作吗?

public class ObjectName {
    private int value1;
    private int value2;
    private int value3;

    public ObjectName (int pValue1, int pValue2, int Value3) {
        value1 = pValue1;
        value2 = pValue2;
        value3 = pValue3;
    }

    // Get Statements for each value below
    public int getValue1() {
        return value1;
    } 
    // etc

请问您能否描述一下这些对象是什么?提供一些相关代码会非常有帮助。 - Mandel
你的Parcelable有什么问题吗?按照你想要使用的方式添加代码作为Parcelable。 - matsjoe
每个对象都包含一些字符串字段和整数,我将在上面添加一些代码。 - James Dudley
以上显示的错误让我感到困惑。谢谢。 - James Dudley
你的对象类是否实现了Parcelable接口?我认为你需要为你的对象类实现Parcelable接口,才能使上述代码正常工作。 - Mandel
更新了objectName代码示例。我需要更改它才能正常工作吗? - James Dudley
10个回答

49

你的对象类应该实现Parcelable接口。下面的代码可以帮助你入手。

    public class ObjectName implements Parcelable {

    // Your existing code

        public ObjectName(Parcel in) {
            super(); 
            readFromParcel(in);
        }

        public static final Parcelable.Creator<ObjectName> CREATOR = new Parcelable.Creator<ObjectName>() {
            public ObjectName createFromParcel(Parcel in) {
                return new ObjectName(in);
            }

            public ObjectName[] newArray(int size) {

                return new ObjectName[size];
            }

        };

        public void readFromParcel(Parcel in) {
          Value1 = in.readInt();
          Value2 = in.readInt();
          Value3 = in.readInt();

        }
        public int describeContents() {
            return 0;
        }

        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(Value1);
            dest.writeInt(Value2);  
            dest.writeInt(Value3);
       }
    }

要使用上述内容,请执行以下操作:

在“发送”活动中使用:

ArrayList<ObjectName> arraylist = new Arraylist<ObjectName>();  
Bundle bundle = new Bundle();  
bundle.putParcelableArrayList("arraylist", arraylist);
在“接收”活动中使用:
Bundle extras = getIntent().getExtras();  
ArrayList<ObjectName> arraylist  = extras.getParcelableArrayList("arraylist");  
ObjectName object1 = arrayList[0];

等等其他的。


在创建 Parcelable 对象后,如何获取其值?我以前没有使用过。例如,对于包含对象的 ArrayList,可以通过 arrlist.getvalue1() 来获取 value1 的值。谢谢。 - James Dudley
很抱歉让您麻烦了。目前我是通过"new ObjectName(value1, value2, value3)"创建一个新对象,并将其添加到ArrayList中。使用parcelables,您现在该如何创建ObjectName对象呢?感谢您的时间。 - James Dudley
@James 你是在问如何在接收活动中检索对象吗?我不理解你的问题。 - Mandel
@James 你可以按照通常的方式创建对象名称的ArrayList,没有“parcelable”方式来创建它。一旦你有了ArrayList,你可以使用我上面展示的代码,使用bundle将其发送到新的活动中。 - Mandel
我错过的关键是你必须使用ArrayList。你不能使用List接口:List<ObjectName> arraylist = new Arraylist<ObjectName>(); - tir38
显示剩余2条评论

22

非常简单的方法,请尝试以下步骤:

bundle.putSerializable("lstContact", (Serializable) lstObject);
lstObj = (List<Contacts>) bundle.getSerializable("lstContact");

同时,您还需要将联系人类实现Serializable接口。

例如:

public class Contact implements Serializable{
   ...
   ...
   ...
}

14

你有两个选择:

Android通过序列化和反序列化(通过Serializable或Parcelable)传递Bundle中的对象。因此,您想要传递到Bundle中的所有对象都必须实现这两个接口之一。

大多数对象很容易使用Serializable进行序列化,而且实现Serializable并为类添加静态UID要比编写Parcelable所需的所有方法/类简单得多。


3
无法使用putSerializable,因为它要求ArrayList是<Integer>或<String>等类型,但无法适用于ArrayList<myObject>。 - localhost
3
如果myObject实现了Serializable接口,那么它就能正常工作。 - dontocsata
3
必须使用 ArrayList<SerializableObject> 而不是 List<SerializableObject>。 - Johny19

2

您可以使用Serializable接口传递您的ArrayList。(序列化是将对象转换为字节流以便将对象存储或传输到内存、数据库或文件中的过程。)

public class ObjectName implements Serializable{
    private int Value1;
    private int Value2;
    private int Value3;

    public ObjectName (int pValue1, int pValue2, int Value3) {
        Value1 = pValue1;
        Value2 = pValue2;
        Value3 = pValue3;
    }

    // Get Statements for each value below
    public int getValue1() {
        return Value1;
    } 
    // etc
}

现在在您当前的活动中

// here is the arrayList of yours
ArrayList<ObjectName> objNamesList = new ArrayList<>();
objNamesList.add(new ObjectName(1,1,1)); 
objNamesList.add(new ObjectName(2,2,2)); 
//intialize bundle instance
Bundle b = new Bundle();
//adding data into the bundle 
//key => objNames referece for the arrayList
//value => objNamesList , name of the arrayList 
//cast the arraylist into Serializable 
b.putSerializable("objNames", (Serializable) objNamesList);
//init the intent
Intent i = new Intent(CurrentActivity.this, NextActivity.class);
i.putExtras(b);
startActivity(i);

在下一个活动中,您需要按照以下步骤获取ArrayList:

public class NextActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next_activity);
        // get the bundle
        Bundle b = getIntent().getExtras();
        ArrayList<ObjectName> q = (ArrayList<ObjectName>) b.getSerializable("objNames");
    }
}

1

0
1)确保您要封装的对象已经正确实现了Parcelable
2)在putParcelableArrayList中使用这个参数:new ArrayList<>(list)。 示例:
    protected void onSaveInstanceState(Bundle outstate) {
        super.onSaveInstanceState(outstate);
        outstate.putParcelableArrayList("myObjects", new ArrayList<>(myListOfObjects));
    }

0
当我需要这样做时,我只需将对象的ArrayList放入extras bundle中(必须是ArrayList,List显然不可序列化)。然后你所要做的就是确保列表内部的对象也是可序列化的。

0

对我有帮助的是: 在写入包裹时设置所有值。如果任何值为NULL,则为该特定属性设置默认值。 一些参数的空值被设置,这就是为什么会抛出此错误的原因。


-1

我曾经遇到同样的问题,后来发现了一个更好的方法,就是将我的数组放在全局类中,这样可以在所有活动中访问。感谢this的帖子,描述了如何使用全局变量,在多个活动中访问。

我的全局类是

public class GlobalClass extends Application{ public MyObject[] objArray }

Android清单更改

android:name=".GlobalClass"

作为多个活动中的访问对象

GlobalClass g = (GlobalClass)getApplicationContext();
g.objArray[0].x = 100;
int x = g.objArray[0].x;

为了更好地理解,请阅读本文。

-1

在您的一些类中,您可以使用public static字段。

有关更多建议,请参见此处


1
可以这样做,但并不鼓励:安卓系统有可能会在没有警告的情况下将静态字段设置为 null... 网上有很多关于此问题的警告和建议:https://dev59.com/BnE95IYBdhLWcg3wDpqg - Alexandru Cristescu
这是文档提出的解决方案之一,所以我认为这并不被反对。你链接中的大多数答案都说静态字段是可以的(也没有人说静态字段会变成null)。 - Guillaume Brunerie
静态字段对于最终数据来说是完全可以的;“public static final int WHATEVER = 0”。第一次访问类时,静态字段将被初始化并保持到类卸载为止。然而,使用静态字段传递数据是懒惰和不安全的。Android提供了许多机制来实现这一点。如果把所有东西都倒入静态字段中就像Bundle类那样容易,那么它将几乎没有用处。 - protectedmember
这是不被鼓励的。违反了Android松耦合的Activity-Fragment设计范例。 - Samuel Robert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接