簡體   English   中英

Android - 通過意圖傳遞哈希圖

[英]Android - passing hashmap through intent

我正在嘗試通過意圖傳遞自定義對象的 Hashmap。

我正在嘗試使用parcelable,因為這就是我讀到的在android中做事的正確方法(即parcelable over serializable)。

但是,當我嘗試使用 getParcelable 獲取哈希圖時,它無法在意圖中找到我的哈希圖,但 getSerializable 可以。

可以對哈希圖使用可序列化嗎? 這是我唯一的選擇嗎?

您當然可以序列化您的地圖,只要您的對象是可序列化的。 您還可以做的是創建一個單獨的單例類(DataStore 左右?)來保存您的數據。 這樣您就不需要將數據從 Activity 傳遞到 Activity。 或者,更簡單的是,將數據保存在公共靜態變量中。

java.util.HashMap不是Parcelable ,所以你的選擇是:

  • 使用 put/getSerializable,它可以在您的應用程序中正常工作
  • 如果在您的應用程序之外發送,請將 HashMap 編碼為 json 或其他遠程格式
  • 將map條目一一取出,直接放入Bundle中(假設有字符串key)

您必須添加一個“包裝器”。 這是丑陋的,但工作...

/**
 * Provides a way to wrap a serializable {@link Map} in order to preserve its class
 * during serialization inside an {@link Intent}, otherwise it would be "flattened"
 * in a {@link android.os.Parcel} and unparceled as a {@link java.util.HashMap}.
 */
public class MapWrapper<T extends Map & Serializable> implements Serializable {

    private final T map;

    public MapWrapper(@NonNull T map) {
        this.map = map;
    }

    public T getMap() {
        return map;
    }

    /**
     * Add extra map data to the intent. The name must include a package prefix, for example
     * the app com.android.contacts would use names like "com.android.contacts.ShowAll".
     * <p>
     * The provided map will be wrapped to preserve its class during serialization.
     * Use {@link #getMapExtra(Intent, String)} to deserialize it.
     *
     * @param intent The intent to add data to.
     * @param name   The name of the extra data, with package prefix.
     * @param map    The map data value.
     *
     * @return The same {@link Intent} object, for chaining multiple calls into a single statement.
     *
     * @see Intent#putExtra(String, Serializable)
     */
    @NonNull
    public static <T extends Map & Serializable> Intent putMapExtra(
            @NonNull Intent intent, @NonNull String name, @NonNull T map) {
        return intent.putExtra(name, new MapWrapper<>(map));
    }

    /**
     * Retrieve extra map data from the intent.
     *
     * @param intent The intent to retrieve data from.
     * @param name   The name of the desired extra item.
     *
     * @return The value of an extra map item that was previously added with
     * {@link #putMapExtra(Intent, String, Map)} or {@code null} if no data was found.
     *
     * @throws ClassCastException
     * If the {@link Serializable} object with the specified name is not of type
     * {@link MapWrapper} or if the wrapped {@code Map} is not of type {@link T}.
     * 
     * @see Intent#getSerializableExtra(String)
     */
    @Nullable
    public static <T extends Map & Serializable> T getMapExtra(
            @NonNull Intent intent, @NonNull String name)
            throws ClassCastException {
        final Serializable s = intent.getSerializableExtra(name);
        //noinspection unchecked
        return s == null ? null : ((MapWrapper<T>)s).getMap();
    }

}

有關https://medium.com/the-wtf-files/the-mysterious-case-of-the-bundle-and-the-map-7b15279a794e 的更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM