【问题标题】:passing java.util.map to another activity将 java.util.map 传递给另一个活动
【发布时间】:2016-02-25 03:59:58
【问题描述】:

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

MainActivity 类:

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


SecondActivity 类:

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


类实现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];
        }
    };    
}


错误日志:

致命异常:主要 进程:com.hsk.hallymloginprac,PID:8071 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.hsk.hallymloginprac/com.hsk.hallymloginprac.MenuActivity}:java.lang.NullPointerException 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2436) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495) 在 android.app.ActivityThread.access$900(ActivityThread.java:170) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:146) 在 android.app.ActivityThread.main(ActivityThread.java:5635) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) 在 dalvik.system.NativeStart.main(本机方法) 引起:java.lang.NullPointerException 在 android.os.Parcel.readMapInternal(Parcel.java:2305) 在 android.os.Parcel.readMap(Parcel.java:1575) 在 com.hsk.hallymloginprac.DataPasser.(DataPasser.java:37) 在 com.hsk.hallymloginprac.DataPasser$1.createFromParcel(DataPasser.java:83) 在 com.hsk.hallymloginprac.DataPasser$1.createFromParcel(DataPasser.java:81) 在 android.os.Parcel.readParcelable(Parcel.java:2111) 在 android.os.Parcel.readValue(Parcel.java:2020) 在 android.os.Parcel.readArrayMapInternal(Parcel.java:2321) 在 android.os.Bundle.unparcel(Bundle.java:249) 在 android.os.Bundle.getParcelable(Bundle.java:1206) 在 android.content.Intent.getParcelableExtra(Intent.java:5292) 在 com.hsk.hallymloginprac.MenuActivity.onCreate(MenuActivity.java:44) 在 android.app.Activity.performCreate(Activity.java:5580) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2400) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2495) 在 android.app.ActivityThread.access$900(ActivityThread.java:170) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1304) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:146) 在 android.app.ActivityThread.main(ActivityThread.java:5635) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) 在 dalvik.system.NativeStart.main(本机方法)

但是,我在 DataPasser 类中有一个 NullPointerException
如何将Map&lt;String, String&gt; 传递给另一个活动?

【问题讨论】:

  • 当你说 It's because Exception 时,那么发布 StackTrace 总是一个好习惯。
  • 你有没有初始化你正在经过的地图。检查 cookie 数组可能为空的任何极端情况。
  • @ShreeKrishna 好的。我不知道。我刚刚添加了 StackTrace。
  • DataPasser 班级的第 83 行是什么?
  • @n.arrow001 我试过了。没有例外。但是,cookies 没有传递给 SecondActivity

标签: android jsoup parcelable


【解决方案1】:

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

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

更新

以 Person 为例,您的 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));
        }

【讨论】:

  • 感谢您的评论。能给我简单的示例代码吗?
  • @Chris 我在更新中添加了简单的例子看看。
【解决方案2】:

另一种可能的解决方案是在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

【讨论】:

    【解决方案3】:

    您还可以尝试另一件事。换个试试

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

    因为根据Parcel.java的文档,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 返回 null 因此 'key' 和 'value' 的值为 null

    outVal.put(key,value)
    

    因此出现 NullPointerException

    【讨论】:

      猜你喜欢
      • 2017-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多