将 java.util.map 传递给另一个 activity

passing java.util.map to another activity

我正在使用 Jsoup 解析网站。
我在 MainActivity 中有一个 Map<String, String> cookies
我需要将值 cookies 传递给 SecondActivity
所以我创建了一个 class 工具 Pracelable

主要活动class:

DataPasser dataPass = new DataPasser(id, pw, cookies);
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("data", dataPass);
MainActivity.this.startActivity(intent);


第二个活动class:

dataPasser dataPass = getIntent().getParcelableExtra("data");
String id = dataPass.getId();
String pw = dataPass.getPw();
Map<String, String> cookies = dataPass.getCookies();


class 实现 Parcelable:

public class DataPasser implements Parcelable {

    private String id;
    private String pw;
    Map<String, String> cookies;

    public String getId() {
        return id;
    }

    public String getPw() {
        return pw;
    }

    public Map<String, String> getCookies() {
        return cookies;
    }

    public DataPasser(Parcel in) {
        this.id = in.readString();
        this.pw = in.readString();
        in.readMap(cookies, Map.class.getClassLoader()); /** NullPointerException here. **/
    }

    public DataPasser(String id, String pw, Map<String, String> cookies) {
        this.id = id;
        this.pw = pw;
        this.cookies = cookies;
    }


    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(id);
        out.writeString(pw);
        out.writeMap(cookies);        
    }

    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<DataPasser> CREATOR = new Parcelable.Creator<DataPasser>() {
        public DataPasser createFromParcel(Parcel in) {
            return new DataPasser(in);
        }
        public DataPasser[] newArray (int size) {
            return new DataPasser[size];
        }
    };    
}


错误日志:

FATAL EXCEPTION: main Process: com.hsk.hallymloginprac, PID: 8071 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hsk.hallymloginprac/com.hsk.hallymloginprac.MenuActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2436) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495) at android.app.ActivityThread.access0(ActivityThread.java:170) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5635) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at android.os.Parcel.readMapInternal(Parcel.java:2305) at android.os.Parcel.readMap(Parcel.java:1575) at com.hsk.hallymloginprac.DataPasser.(DataPasser.java:37) at com.hsk.hallymloginprac.DataPasser.createFromParcel(DataPasser.java:83) at com.hsk.hallymloginprac.DataPasser.createFromParcel(DataPasser.java:81) at android.os.Parcel.readParcelable(Parcel.java:2111) at android.os.Parcel.readValue(Parcel.java:2020) at android.os.Parcel.readArrayMapInternal(Parcel.java:2321) at android.os.Bundle.unparcel(Bundle.java:249) at android.os.Bundle.getParcelable(Bundle.java:1206) at android.content.Intent.getParcelableExtra(Intent.java:5292) at com.hsk.hallymloginprac.MenuActivity.onCreate(MenuActivity.java:44) at android.app.Activity.performCreate(Activity.java:5580) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2400) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495)  at android.app.ActivityThread.access0(ActivityThread.java:170)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:146)  at android.app.ActivityThread.main(ActivityThread.java:5635)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)  at dalvik.system.NativeStart.main(Native Method) 

但是,我在 DataPasser class 中得到了一个 NullPointerException
如何将 Map<String, String> 传递给另一个 activity?

我无法确定您的实际问题,但我可以建议您使用 writeBundle instead of writeMap。同样根据文档,强烈建议使用 writeBundle(Bundle) 而不是此方法,因为 Bundle class 提供了类型安全的 API 可以避免神秘的类型错误编组点。

您可以使用 readBundle() which was written with writeBundle 轻松读取数据。它会 从当前 dataPosition() 的包裹中读取并 return 一个新的 Bundle 对象。如果再次提出问题,请发表评论。

更新

以人为例,您的 writeToParcel 看起来像这样,

 @Override
    public void writeToParcel(Parcel dest, int flags) {
        // create a bundle for the key value pairs
        Bundle bundle = new Bundle();

        // insert the key value pairs to the bundle
        bundle.putString(KEY_NAME, name);
        bundle.putInt(KEY_AGE, age);

        // write the key value pairs to the parcel
        dest.writeBundle(bundle);
    }

createFromParcel 方法如下所示,

@Override
        public Person createFromParcel(Parcel source) {
            // read the bundle containing key value pairs from the parcel
            Bundle bundle = source.readBundle();

            // instantiate a person using values from the bundle
            return new Person(bundle.getString(KEY_NAME),
                                bundle.getInt(KEY_AGE));
        }

另一种可能的解决方案是在DataPasser

中实现Serializable接口
public class DataPasser implements Serializable {

像您一样从 MainActivity.java 传递数据

DataPasser dataPass = new DataPasser(id, pw, cookies);
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("data", dataPass);
MainActivity.this.startActivity(intent);

并在 SecondActivity.java 中得到相同的结果

DataPasser dataPass = (DataPasser) getIntent().getExtras().get("data");

然后访问 DataPasser.

的元素

我的 pojo 类。

希望它能奏效。

参考 this 也适用于 Parcelable

您还可以尝试一件事。尝试替换

public DataPasser(Parcel in) {
    this.id = in.readString();
    this.pw = in.readString();
    in.readMap(cookies, Map.class.getClassLoader());
}

public DataPasser(Parcel in) {
    this.id = in.readString();
    this.pw = in.readString();
    in.readMap(cookies, String.class.getClassLoader()); 
}

因为根据[=31=的文档],方法readMap是

public final void readMap(Map outVal, ClassLoader loader) {
    int N = readInt();
    readMapInternal(outVal, N, loader);
}

调用

void readMapInternal(Map outVal, int N,
    ClassLoader loader) {
    while (N > 0) {
        Object key = readValue(loader);
        Object value = readValue(loader);
        outVal.put(key, value);
        N--;
    }
}

所以在这里,readValue 尝试加载 map 类型的值作为 map 的 'key' 和 'value'。 readValue returns null 因此 'key' 和 'value' 的值对于

是 null
outVal.put(key,value)

因此出现 NullPointerException