【问题标题】:Passing an ArrayList of Objects to the new Activity将对象的 ArrayList 传递给新的 Activity
【发布时间】:2011-07-13 15:15:42
【问题描述】:

我有一个对象的 ArrayList。即ArrayList<ObjectName>

我想将此传递给新的Activity。我尝试使用putParcelableArrayList,但对象存在问题。我从变量的创建中删除了<ObjectName> 部分,该方法有效,但随后我得到 eclipse 抱怨不安全的东西。

如何将这个ArrayList<ObjectName> 传递给新的活动

感谢您的宝贵时间

编辑 我试过这个:

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

EDIT2 对象示例代码。我需要更改此设置以使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

【问题讨论】:

  • 您能描述一下这些对象是什么吗?一些相关的代码会很有用。
  • 您的包裹有什么问题?将代码添加为 parcelable 是您想要使用的方式。
  • 创建的每个对象都包含许多字符串字段和整数。我将在上面添加一些代码
  • 对上面显示的错误感到困惑。谢谢
  • 你的对象类是否实现了parcelable?我认为您应该为您的对象类实现 parcelable 以使上述代码正常工作。

标签: android


【解决方案1】:

你的对象类应该实现 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,它是 value1=arrlist.getvalue1();谢谢
  • 很抱歉,我很痛苦。目前我通过“new ObjectName(value1, value2, value3)”创建了一个新对象并将其添加到 Arraylist。现在使用 parcelables 如何创建 ObjectName。感谢您的时间
  • @James 您是在询问如何在接收活动中检索对象吗?我不明白你的问题。
  • 您已经在上面展示了如何在新活动中检索对象。那是完美的。但是我该如何使用 parcelable 而不是直接对象类来创建 ObjectName 的 ArrayList。谢谢
  • @James 您以通常的方式创建对象名称的数组列表。没有“可打包”的方式来创建它。一旦你有了数组列表,你就可以使用捆绑包通过上面显示的代码将它发送到新活动。
【解决方案2】:

非常简单的方法,试试以下方法:

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

你还需要从 Serializable 接口实现你的 Contact 类。 例如:

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

【讨论】:

    【解决方案3】:

    你有两个选择:

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

    使用Serializable 可以轻松序列化大多数对象,实现Serializable 并向类添加静态UID 比编写Parcelable 所需的所有方法/类要简单得多。

    【讨论】:

    • putSerializable 在这里不起作用,因为它要求 ArrayList 为 等,但不能应用于 ArrayList
    • 如果myObject实现了Serializable,那么它就可以工作了。
    • 它必须是 ArrayList 而不是 List
    【解决方案4】:

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

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

    在下一个活动中,您需要执行以下操作来获取数组列表

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

    【讨论】:

      【解决方案5】:

      查看putParcelableArrayList 的文档,您的ObjectName 似乎需要扩展“Parcelable”接口才能使其正常工作。您收到的错误似乎也表明了这一点。

      我会看这里:http://developer.android.com/reference/android/os/Parcelable.html

      【讨论】:

        【解决方案6】:

        当我不得不这样做时,我只是将对象的 ArrayList 放入 extras 包中(它必须是 ArrayList,List 显然不可序列化)。那么你所要做的就是确保列表中的对象也是可序列化的。

        【讨论】:

          【解决方案7】:

          1) 确保你要打包的对象已经正确实现Parcelable

          2) 在putParcelableArrayList 中使用这个参数:new ArrayList(list)

          示例:

              protected void onSaveInstanceState(Bundle outstate) {
                  super.onSaveInstanceState(outstate);
                  outstate.putParcelableArrayList("myObjects", new ArrayList<>(myListOfObjects));
              }
          

          【讨论】:

            【解决方案8】:

            帮助我的是: 在写入包裹时设置所有值。如果任何值为 NULL,我将为该特定属性设置默认值。 为几个参数设置了空值,这就是引发此错误的原因。

            【讨论】:

              【解决方案9】:

              您可以在某些类中使用public static 字段。

              更多建议请参见here

              【讨论】:

              • 你可以,但它相当气馁:android系统可以简单地使静态字段为空而没有警告......网上有很多关于这个的警告:stackoverflow.com/questions/2475978/…
              • 这是文档提出的解决方案之一,所以我不认为这是不鼓励的。您链接上的大多数答案都说静态字段是可以的(没有人说静态字段可以变为空)
              • 静态字段绝对适合最终数据; “公共静态最终 int WHATEVER = 0”。第一次访问该类时,静态字段被初始化并一直保留到该类被卸载。但是,使用静态字段来传递数据是懒惰且不安全的。 Android 提供了许多机制来实现这一点。如果像在静态字段中转储所有内容一样简单,那么像 Bundle 这样的类就没什么用了。
              • 不鼓励这样做.. 反对 android 松散耦合的活动片段设计范式
              【解决方案10】:

              我在同一个问题上苦苦挣扎,并找到了一种更好的方法,可以将我的数组放入可以在所有活动中访问的全局类中。感谢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;
              

              为了更好地理解,请浏览帖子。

              【讨论】:

                猜你喜欢
                • 2014-03-13
                • 2017-01-25
                • 2016-07-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-05-10
                • 2020-06-05
                相关资源
                最近更新 更多