【问题标题】:Pass LinkedList to another activity将 LinkedList 传递给另一个活动
【发布时间】:2016-11-19 01:35:53
【问题描述】:

我在一个活动 (A) 中有一个链接列表,我想与另一个活动 (B) 共享。 该列表包含字符串类型的用户名和 LatLng 类型的坐标。我还使用 Intent 和 bundle 在活动之间共享数据。我尝试使用 Parcelable 但无法弄清楚如何使用它。这是我的代码:

数据.java

public class data implements Parcelable{
    private LatLng coordinates;
    private String name;


    public data() {
        name = null;
        coordinates = null;
    }

    public data(String name, LatLng coordinates)
    {
        this.name = name;
        this.coordinates = coordinates;
    }

    public data(Parcel in) {
        coordinates = in.readParcelable(LatLng.class.getClassLoader());
        name = in.readString();
    }

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

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

    public LatLng getLatLng () {
        return coordinates;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeParcelable(coordinates, flags);
    }
}

活动 A

public class A extends FragmentActivity implements
    OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    GoogleMap.OnMyLocationButtonClickListener,
    ActivityCompat.OnRequestPermissionsResultCallback {

    Button switchToSeek;
    double mLatitude;
    double mLongitude;

    LinkedList<data> storedData = new LinkedList<>();

    protected void onCreate(Bundle savedInstanceState) {
        ...
        switchToSeek.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        getCurrentLocation();

                        Intent intent = new Intent(A.this, B.class);

                        Bundle xy = new Bundle();
                        xy.putDouble("x", mLatitude);
                        xy.putDouble("y", mLongitude);
                        xy.putParcelable("list", storedData); <---------- error: wrong second arugment

                        intent.putExtra("xy", xy);
                        A.this.startActivity(intent);
                    }
                });

活动 B

public class B extends FragmentActivity implements OnMapReadyCallback {

    double mLatitude;
    double mLongitude;
    LatLng current;
    GoogleMap gMap;

    LinkedList <data> copyData = new LinkedList<>();

    @Override
        public void onMapReady(GoogleMap googleMap) {
            gMap = googleMap;

            ...

            Intent intent = getIntent();
            Bundle xy = intent.getBundleExtra("xy");

            if (xy != null) {
                mLatitude = xy.getDouble("x");
                mLongitude = xy.getDouble("y");
            }
           /***** Call linked list here and set equal to copyData *****/

            current = new LatLng(mLatitude, mLongitude);
            gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(current, 18.0f));

        }

【问题讨论】:

  • 您可以将列表转换为数组,然后再转换为字符串。将带有意图的字符串传递给活动,用“,”将其拆分,并将元素存储在另一个数组中,最后遍历该数组并将元素添加到另一个活动中的数组列表中。

标签: android android-intent parcelable android-bundle


【解决方案1】:

没有简单的方法可以做到这一点,因为 LinkedList 没有实现可序列化或可打包。

您可以实现自己的链表类,并使其成为可序列化/可打包的对象,然后可以传递。

或者您可以将其内容转换为另一种数据类型,例如数组,然后重新创建链表。* 这是非常低效的

我相信还有其他方法,但这是 android dev 中的标准问题。如果可能的话,也许尝试使用片段并通过 setter() 传递链表

【讨论】:

  • 是的,我注意到了。我想使用的 bundle 或 intent 的所有函数都用于 arrayList。我考虑过转换,但就像你说的那样效率很低,特别是如果我想在列表中存储大量数据
【解决方案2】:

如果列表不大,您可以使用以下帮助类来完成:

public class ParcelableLinkedList<E extends Parcelable> implements Parcelable {

    private final LinkedList<E> linkedList;

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

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

    public ParcelableLinkedList(Parcel in) {
        // Read size of list
        int size = in.readInt();
        // Read the list
        linkedList = new LinkedList<E>();
        for (int i = 0; i < size; i++) {
            linkedList.add((E)in.readParcelable(ParcelableLinkedList.class.getClassLoader()));
        }

    }

    public ParcelableLinkedList(LinkedList<E> linkedList) {
        this.linkedList = linkedList;
    }

    LinkedList<E> getLinkedList() {
        return linkedList;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        // Write size of the list
        parcel.writeInt(linkedList.size());
        // Write the list
        for (E entry : linkedList) {
            parcel.writeParcelable(entry, flags);
        }
    }
}

在您的onClick() 方法中,将数据添加到Bundle,如下所示:

xy.putParcelable("list", new ParcelableLinkedList<data>(storedData));

要从Bundle 中提取数据,请执行以下操作:

copyData = ((ParcelableLinkedList<data>)xy.getParcelable("list")).getLinkedList();

我还没有实际编译和测试过这段代码,但它应该可以工作。

如果列表真的很大,最好将它存储在一个类的static 成员变量中,然后从另一个类中引用它。这通常不是你想要在 Android 中做事的方式,但有时这样做比序列化和反序列化大量数据只是为了在可以访问相同内存空间的 2 个活动之间传递它更方便。

【讨论】:

  • I got java.util.ConcurrentModificationException on @Override public void writeToParcel(Parcel parcel, int flags) { // 写入列表的大小 parcel.writeInt(linkedList.size()); // 为 (E entry : linkedList) { parcel.writeParcelable(entry, flags); } }
猜你喜欢
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多