在Activity之间传递包含Map的parcelable对象

A. *_*olf 5 android parcelable android-intent android-activity

我的类ExpenseFB,它实现Parcelable,包含MapUserFB(实现Parcelable过):

ExpenseFB:

public class ExpenseFB implements Parcelable {

private String id;
private String name;
private String description;
private String whopaidID;
private String whopaidName;
private Double amount;
private Map<String, UserFB> partecipants;
// setters and getters...
@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(name);
    dest.writeString(description);
    dest.writeString(whopaidID);
    dest.writeString(whopaidName);
    dest.writeMap(partecipants);
}


protected ExpenseFB(Parcel in) {
    id = in.readString();
    name = in.readString();
    description = in.readString();
    whopaidID = in.readString();
    whopaidName = in.readString();
    in.readMap(partecipants,UserFB.class.getClassLoader());
}

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

    @Override
    public ExpenseFB[] newArray(int size) {
        return new ExpenseFB[size];
    }
};
}
Run Code Online (Sandbox Code Playgroud)

UserFB:

public class UserFB implements Parcelable{

private String id;
private String name;
private String email;
private Map<String, GroupFB> groups;
private Map<String, UserFB> friends;
// setters and getters
@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(name);
    dest.writeString(email);
    dest.writeMap(groups);
    dest.writeMap(friends);
}

protected UserFB(Parcel in) {
    id = in.readString();
    name = in.readString();
    email = in.readString();
    in.readMap(groups,GroupFB.class.getClassLoader());
    in.readMap(friends,UserFB.class.getClassLoader());
}

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

    @Override
    public UserFB[] newArray(int size) {
        return new UserFB[size];
    }
};
}
Run Code Online (Sandbox Code Playgroud)

我想通过将对象添加ExpenseFB到intent中来在两个活动之间传递ExpenseFB对象 :

intent.putExtra("id", expenseFB);
Run Code Online (Sandbox Code Playgroud)

在调试模式下,我getIntent().getParcelableExtra("id")在第二个活动中执行时,尝试readMap()partecipants地图上执行该方法时会引发以下异常:

 ... Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.Map.put(java.lang.Object, java.lang.Object)' on a null object reference
Run Code Online (Sandbox Code Playgroud)

我看到partecipants第一个活动中的地图已填充:我认为问题出在writeMap()方法中.
是否存在传递Parcelable包含Map 的对象的标准或更好的方法?
我是否要调用另一种方法来包裹地图?

我不想使用Serializable对象,因为我读到他们的表现更差.

Dav*_*ser 7

问题是readMap()用于从Parcel进入和现有Map数据中读取数据.你没有创建Map之前的呼叫readMap(),所以你得到了NullPointerException.

您可以通过在声明时初始化地图来解决此问题:

private Map<String, GroupFB> groups = new HashMap<String, GroupFB>();
private Map<String, UserFB> friends = new HashMap<String, UserFB>();
Run Code Online (Sandbox Code Playgroud)

或者,您可以MapUserFB构造函数中创建空,如下所示:

protected UserFB(Parcel in) {
    id = in.readString();
    name = in.readString();
    email = in.readString();
    groups = new HashMap<String, GroupFB>();
    in.readMap(groups,GroupFB.class.getClassLoader());
    friends = new HashMap<String, UserFB>()
    in.readMap(friends,UserFB.class.getClassLoader());
}
Run Code Online (Sandbox Code Playgroud)