我正在将AndroidX Room组件用于我的应用程序中的小型离线数据库。我希望能够将用户的位置(纬度和经度)保存到数据库中,并在以后使用。 怎么做以及最佳做法是什么?
我以前从未做过,也无法在网络上找到任何帮助。
这就是我的实际操作方式(显然是错误的方式):
@ColumnInfo(name = "session_location")
var sessionLocation: Location
我收到一个错误 Cannot figure out how to save this field into database
答案 0 :(得分:1)
您的Location
类是什么?是android.location.Location
还是您定义的某个数据类?
无论如何,我都会使用@Embedded
POJO类而不是其他人推荐的TypeConverters
。
如果Location
是您已经定义的类,则只需在sessionLocation顶部添加@Embedded
注释
@Embedded
@ColumnInfo(name = "session_location")
var sessionLocation: Location
否则,如果Location
是android.location.Location
,则您无需将所有信息存储在该类中。您必须使用lat & long
的基本密码。
我将刚刚创建一个类Location
并存储这些基本信息,并将其添加为@Embedded
。像下面这样
class Location {
var latitude: Double = 0
var longitude: Double = 0
}
class User {
@Embedded
@ColumnInfo(name = "session_location")
var sessionLocation: Location
}
正如其他人所建议的,TypeConverter
是一种解决方案,但是当您可以直接保存它时,无需序列化/反序列化POJO
。
答案 1 :(得分:0)
您应为Room不支持的类型定义自己的转换器。基本上,SQLite仅支持原始类型作为列字段。 对于每种复杂数据类型,您必须定义一个自定义转换器,因为Room不知道如何在数据库列中序列化您的复杂类型。 为此,您需要创建一个转换器,该转换器负责在原始字段中转换复杂的结构化类型:
例如(来自android文档)
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time?.toLong()
}
}
在您的情况下,最简单的方法是使用 GSON 将对象序列化为JSON字符串(当您写入数据库时-Room支持字符串),然后将数据库中的字符串解析为从数据库中读取您的Location
对象
在您的情况下,我会做类似的事情:
class LocationConverter {
@TypeConverter
fun toLocation(locationString: String?): Location? {
return try {
Gson().fromJson(locationString, Location::class.java)
} catch (e: Exception) {
null
}
}
@TypeConverter
fun toLocationString(location: Location?): String? {
return Gson().toJson(location)
}
}
完成转换器后,请使用刚刚定义的LocationConverter
为数据库添加注释!
@TypeConverters(LocationConverter::class)
abstract class YourDatabase : RoomDatabase() {
// your code
}