【问题标题】:Passing an arraylist of arraylists传递数组列表的数组列表
【发布时间】:2018-07-31 14:21:27
【问题描述】:

我知道这是一个常见问题,并且我在网上查看了解决方案,但我在自己实施时遇到了困难。

我有一个包含三个变量的类:LocationDateUri

我有一个Arraylist,它由多个包含所述类的数组列表组成。

例如:

ArrayList<ArrayList<class>>

我正在尝试将此传递给另一个活动,但未成功。 我尝试了ParcelableSerializable,但都没有成功。

编辑:添加源代码。

类文档:

public class imageHolder implements Parcelable
{
private Uri uri;
private Date date;
private Location loc;

public imageHolder(Uri uriAdd, Date dateAdded,Location imgLoc)
{
    this.uri = uriAdd;
    this.date = dateAdded;
    this.loc = imgLoc;
}


public static final Creator<imageHolder> CREATOR = new Creator<imageHolder>() {
    @Override
    public imageHolder createFromParcel(Parcel in) {
        return new imageHolder(in);
    }

    @Override
    public imageHolder[] newArray(int size) {
        return new imageHolder[size];
    }
};

public Uri getURI() { return this.uri; }

public Date getDate() {return this.date; }

public Location getLocation() {return this.loc; };

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeSerializable(date);
    parcel.writeParcelable(uri,i);
    parcel.writeParcelable(loc, i);
}

protected imageHolder(Parcel in) {
    date = (java.util.Date) in.readSerializable();
    uri = in.readParcelable(Uri.class.getClassLoader());
    loc = in.readParcelable(Location.class.getClassLoader());
}

}

第一个活动:

ArrayList<ArrayList<imageHolder>> sepImages = new ArrayList<ArrayList<imageHolder>>();
    sepImages = groupPics(images);


    Intent nextActivity = new Intent(loadImages.this, storiesScreen.class);
    nextActivity.putExtra("images",images);
    startActivity(nextActivity);
    finishActivity(0);

第二次活动:

ArrayList<ArrayList<imageHolder>> sepImages = 
(ArrayList<ArrayList<imageHolder>>) getIntent().getParcelableExtra("images");
Log.d("stories","test");

【问题讨论】:

  • 你能发布源代码吗?顺便说一句,如果它有很多数据,最好使用存储库类型结构。传递大量数据并不是序列化/可打包的真正用途,实际上您可能会遇到问题,因为可打包数据有上限。
  • @breakline 嘿,感谢您的回复。我现在已经添加了源代码。在这些活动之间传递的数据量应该很大。我将很快研究存储库类型结构,尽管我从未听说过。
  • 不是一个答案,只是一些 Java 风格的编码技巧:用大写字母开始你的类。变量以小写字母开头并使用驼峰式风格是正确的。示例:ImageHolder 用于类 imageHolder 用于变量。
  • 您是否打算传递“图像”而不是“sepImages”?

标签: java android arraylist android-activity


【解决方案1】:

我认为最好的办法是创建一个实现Parcelable 的新类,并在活动之间传递这个新类的实例。

public class ParcelableListOfLists implements Parcelable {

    private ArrayList<ArrayList<imageHolder>> listOfLists;

    public ParcelableListOfLists(ArrayList<ArrayList<imageHolder>> listOfLists) {
        this.listOfLists = listOfLists;
    }

    public ArrayList<ArrayList<imageHolder>> getListOfLists() {
        return listOfLists;
    }

    // parcelable implementation here
}

一旦你有了这个类,你就可以完全控制如何你的数据是如何被打包的,这让你可以做一些你无法用 Android 内置的东西做的事情——在供品中。

这是您可以打包列表列表的一种方法:

@Override
public void writeToParcel(Parcel dest, int flags) {
    if (listOfLists != null) {
        dest.writeInt(listOfLists.size());

        for (ArrayList<imageHolder> list : listOfLists) {
            dest.writeTypedList(list);
        }
    } else {
        dest.writeInt(-1);
    }
}

另一方面,您可以像这样重新创建列表列表:

public ParcelableListOfLists(Parcel in) {
    int size = in.readInt();

    if (size != -1) {
        this.listOfLists = new ArrayList<>(size);

        for (int i = 0; i < size; ++i) {
            ArrayList<imageHolder> list = in.createTypedArrayList(imageHolder.CREATOR);
            listOfLists.add(list);
        }
    } else {
        this.listOfLists = null;
    }
}

结合所有这些,您可以在活动之间传递您的列表列表,如下所示:

Intent nextActivity = new Intent(loadImages.this, storiesScreen.class);
nextActivity.putExtra("images", new ParcelableListOfLists(images));
startActivity(nextActivity);

并像这样在下一个活动中检索它们:

ParcelableListOfLists plol = getIntent().getParcelableExtra("images");
ArrayList<ArrayList<imageHolder>> images = plol.getListOfLists();

【讨论】:

  • 嘿。我要试一试。同时,我的问题是,在性能方面,当我必须复制然后重新创建列表时会不会很耗时?考虑到我可能会使用数百张图片。
  • @Tomer 取决于每个 imageHolder 的“大”程度,复制数百可能几乎是瞬时的或非常缓慢。但是,您通过Intent.putExtra() 包裹和发送的任何东西都必须是“小”的,否则您将达到活页夹交易大小限制。只要您的数据在此大小限制内,我怀疑您不必担心性能。
  • 我已经设法在活动之间传递列表并将所有内容移至 AsynTasks,但在某些时候屏幕变黑了大约 7 秒,然后下一个活动出现。某些东西确实会消耗大量时间,使其变黑,但这是另一个问题。感谢您的帮助!
【解决方案2】:

我认为你也可以使用 Gson。

在你的 build.gradle

implementation 'com.google.code.gson:gson:2.8.4'

第一个活动

Gson gson = new Gson();
String json = gson.toJson(yourObject);
intent.putExtra("yourKey", json);

第二个活动

Gson gson = new Gson();
YourObject yourObject = gson.fromJson(getIntent().getStringExtra("yourKey"), YourObject.class);

简单快捷。

【讨论】:

  • 我尝试过使用您的代码,但在第二个活动中它最终以 sepImages 为 NULL。在此命令行上: YourObject yourObject = gson.fromJson(getIntent().getStringExtra("yourKey"), YourObject.class);什么是我的 object.class? ArrayList 还是 imageHolder?
  • 如果你要放置一个 ArrayList 类型的对象,你必须使用 ArrayList.class!你也可以使用 List.class,我敢打赌你也可以使用所有 Object.class :D
  • 给了我同样的错误。 Parcelable 在写入可序列化对象时遇到 IOException
  • 我认为这是因为所有子类和内部子类都必须实现Serializable。
  • 你的 ImageHolder 类必须实现 Serializable,然后使用实现 Serializable 的 ArrayList 或 LinkedList!
【解决方案3】:

好的。

您的模型

public class ImageHolder implements Serializable {

    // Use String here, to avoid serialization problems
    private String uri;
    private Date date;
    private Location loc;

    public ImageHolder() {
    }

    public ImageHolder(String uri, Date date, Location loc) {
        this.uri = uri;
        this.date = date;
        this.loc = loc;
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Location getLoc() {
        return loc;
    }

    public void setLoc(Location loc) {
        this.loc = loc;
    }

    @Override
    public String toString() {
        return "ImageHolder{" +
                "uri=" + uri +
                ", date=" + date +
                ", loc=" + loc +
                '}';
    }
}

创建一个容器

public class Container implements Serializable {

    private ArrayList<ImageHolder> list;

    public Container() {
    }

    public Container(ArrayList<ImageHolder> list) {
        this.list = list;
    }

    public ArrayList<ImageHolder> getList() {
        return list;
    }

    public void setList(ArrayList<ImageHolder> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "Container{" +
                "list=" + list +
                '}';
    }
}

您的第一个活动

public class MainActivity extends AppCompatActivity {

    public static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        ImageHolder imageHolder0 = new ImageHolder("http://www.stackoverflow.com", new Date(), new Location("test0"));
        ImageHolder imageHolder1 = new ImageHolder("http://www.google.com", new Date(), new Location("test1"));

        ArrayList<ImageHolder> list = new ArrayList<>();
        list.add(imageHolder0);
        list.add(imageHolder1);

        Container container = new Container(list);

        Gson gson = new Gson();
        String json = gson.toJson(container);

        Intent intent = new Intent(MainActivity.this, TestActivity.class);
        intent.putExtra("yourKey", json);

        startActivity(intent);
    }
}

您的第二个活动

public class TestActivity extends AppCompatActivity {
    public static final String TAG = TestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        Gson gson = new Gson();
        Container container = gson.fromJson(getIntent().getStringExtra("yourKey"), Container.class);

        Log.d(TAG, "OK?" + container.getList().toString());

        // Here convert String uri Fields to Uri Objects
        // Example:
        Uri uri = Uri.parse(container.getList().get(0).getUri());
    }
}


Logcat 结果:08-01 11:10:22.097 6671-6671/it.darksurfer.english.template D/TestActivity: OK?[ImageHolder{uri=http://www.stackoverflow.com, date=Wed Aug 01 11:10:21 GMT+02:00 2018, loc=Location[test0 0,000000,0,000000 acc=??? t=?!? et=?!?]}, ImageHolder{uri=http://www.google.com, date=Wed Aug 01 11:10:21 GMT+02:00 2018, loc=Location[test1 0,000000,0,000000 acc=??? t=?!? et=?!?]}]



显然你可以在 Container 类的列表中放入未定义数量的其他 ArrayList!

【讨论】:

    猜你喜欢
    • 2011-04-27
    • 2023-03-10
    • 2012-08-23
    • 2012-04-09
    • 2013-03-15
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多