使用parcelable将项目存储为共享首选项?

时间:2015-02-10 18:24:15

标签: java android storage serializable

我有一些对象,位置,在我的应用程序中存储在ArrayList中,并使用parcelable在活动之间移动它们。该对象的代码如下所示:

public class Location implements Parcelable{

private double latitude, longitude;
private int sensors = 1;
private boolean day;
private int cloudiness;

/*
Måste ha samma ordning som writeToParcel för att kunna återskapa objektet.
 */
public Location(Parcel in){
    this.latitude = in.readDouble();
    this.longitude = in.readDouble();
    this.sensors = in.readInt();
}

public Location(double latitude, double longitude){
    super();
    this.latitude = latitude;
    this.longitude = longitude;
}

public void addSensors(){
    sensors++;
}


public void addSensors(int i){
    sensors = sensors + i;
}

+ Some getters and setters.

现在我需要更永久地存储这些对象。我在某处读到了我可以序列化对象并另存为sharedPreferences。我是否必须实现序列化,或者我可以使用parcelable做类似的事情吗?

5 个答案:

答案 0 :(得分:46)

由于parcelable无法帮助您将数据存储在持久存储中(请参阅StenSoft的回答),您可以使用gson来保留您的位置:

保存位置:

String json = location == null ? null : new Gson().toJson(location);
sharedPreferences.edit().putString("location", json).apply();

检索位置:

String json = sharedPreferences.getString("location", null);
return json == null ? null : new Gson().fromJson(json, Location.class);

答案 1 :(得分:26)

来自documentation of Parcel

  

Parcel不是通用序列化机制。此类(以及用于将任意对象放入包中的相应Parcelable API)被设计为高性能IPC传输。因此,将任何Parcel数据放入持久存储中是不合适的:Parcel中任何数据的底层实现的更改都可能导致旧数据不可读。

答案 2 :(得分:0)

如果您使用的是 Kotlin,我会采用 Cristan 的方法,但有一些扩展功能,请参阅:

import android.content.SharedPreferences
import android.os.Parcelable
import com.google.gson.Gson
import com.google.gson.JsonSyntaxException

fun SharedPreferences.Editor.putParcelable(key: String, parcelable: Parcelable) {
    val json = Gson().toJson(parcelable)
    putString(key, json)
}

inline fun <reified T : Parcelable?> SharedPreferences.getParcelable(key: String, default: T): T {
    val json = getString(key, null)
    return try {
        if (json != null)
            Gson().fromJson(json, T::class.java)
        else default
    } catch (_: JsonSyntaxException) {
        default
    }
}

然后您可以按如下方式使用它,用于存储:

sharedPreferences.edit {
    putParcelable("location", location)
}

阅读:

val location = sharedPreferences.getParcelable<Location?>("location", null)

这是使用 Cristan 提案的一种非常干净的方式。希望它对你有用:)

答案 3 :(得分:0)

您可以像创建 Gson'able 和 Parcelable 一样创建类

@Parcelize
data class ApiRate(
    @SerializedName("tp") val tp: Int,
    @SerializedName("name") val name: String,
    @SerializedName("from") val from: Int,
    @SerializedName("currMnemFrom") val currMnemFrom: String,
    @SerializedName("to") val to: Int,
    @SerializedName("currMnemTo") val currMnemTo: String,
    @SerializedName("basic") val basic: String,
    @SerializedName("buy") val buy: String,
    @SerializedName("sale") val sale: String,
    @SerializedName("deltaBuy") val deltaBuy: String,
    @SerializedName("deltaSell") val deltaSell: String
) : Parcelable

可能。

答案 4 :(得分:-3)

首选方式可能是实施IntentService