我对使用json的数据存储不是很熟悉。我有一个非常复杂的对象,基本上只是一个hashmap,见下文:
data class Axis (var BSSID: String, var RSSI: Int)
data class Label (var x: Int, var y: Int)
data class RadioMap(var map: HashMap<Label, ArrayList<Axis>> = HashMap())
我试图在一个SQLite数据库中将RadioMap对象作为TEXT存储在一列中。我能够保存它,但是当我尝试将其转换回来时,我收到此错误 com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期BEGIN_OBJECT但是STRING在第1行第10列路径$ .MAP。
这是我从数据库中保存和检索RadioMap的代码:
fun updateRadioMap(name: String, radioMap: RadioMap) {
val gson = Gson()
val rmString = gson.toJson(radioMap)
val cv = ContentValues()
cv.put(COLUMN_RADIO_MAP_JSON, rmString)
val db = writableDatabase
db.update(TABLE_FLOOR_MAPS, cv, "$COLUMN_FLOOR_NAME = '$name'", null)
db.close()
}
fun getRadioMap(name: String): RadioMap {
val db = this.writableDatabase
val query = "SELECT * FROM $TABLE_FLOOR_MAPS WHERE $COLUMN_FLOOR_NAME =\"$name\";"
val cursor = db.rawQuery(query, null)
return if (cursor != null && cursor.moveToFirst()) {
var rmString = cursor.getString(5)
cursor.close()
db.close()
if (rmString != null) {
val gson = Gson()
gson.fromJson<RadioMap>(rmString, RadioMap::class.java) //APP CRASHES HERE
} else {
RadioMap()
}
} else {
cursor.close()
db.close()
RadioMap()
}
}
修改
这是数据库的onCreate方法:
override fun onCreate(sqLiteDatabase: SQLiteDatabase) {
val query = "CREATE TABLE " + TABLE_FLOOR_MAPS + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY, " +
COLUMN_FLOOR_NAME + " TEXT, " +
COLUMN_FLOOR_IMAGE + " BLOB, " +
COLUMN_FLOOR_WIDTH + " REAL, " +
COLUMN_GRID_SIZE + " REAL, " +
COLUMN_RADIO_MAP_JSON + " TEXT " +
");"
sqLiteDatabase.execSQL(query)
}
但唯一相关的列是最后一列,COLUMN_RADIO_MAP_JSON。
以下是我试图保存的RadioMap示例,其中toString()
被调用:
RadioMap(map = {Label(x = 0,y = 0)= [Axis(BSSID = 78:f2:9e:57:0d:03, RSSI = -93),轴(BSSID = 78:f2:9e:57:0d:04,RSSI = -92), 轴(BSSID = 78:f2:9e:57:0d:01,RSSI = -92),轴(BSSID = 78:f2:9e:57:0d:00, RSSI = -91),轴(BSSID = 78:f2:9e:57:0d:02,RSSI = -91), 轴(BSSID = 54:be:f7:dc:47:ea,RSSI = -90),轴(BSSID = 10:5f:06:83:f1:c5, RSSI = -90),轴(BSSID = 2c:7e:81:c4:70:ee,RSSI = -89), 轴(BSSID = 10:da:43:86:9b:51,RSSI = -89),轴(BSSID = 4e:7e:81:c4:70:ee, RSSI = -89),轴(BSSID = 7e:8f:e0:0a:b6:d5,RSSI = -89), 轴(BSSID = 3e:7e:81:c4:70:ee,RSSI = -88),轴(BSSID = 1c:49:7b:94:92:e1, RSSI = -88),轴(BSSID = 84:00:2d:65:a0:ba,RSSI = -88), 轴(BSSID = 50:c7:bf:89:13:f6,RSSI = -87),轴(BSSID = 3e:7e:81:c4:70:ed, RSSI = -87),轴(BSSID = ea:5d:df:92:49:28,RSSI = -86), 轴(BSSID = da:5d:df:92:49:28,RSSI = -84),轴(BSSID = 54:be:f7:dc:47:e8, RSSI = -76),轴(BSSID = 78:f2:9e:57:0c:fa,RSSI = -73), 轴(BSSID = 78:f2:9e:57:0c:f8,RSSI = -70),轴(BSSID = 44:32:c8:2c:77:b2, RSSI = -54),轴(BSSID = 46:32:c8:2c:77:b4,RSSI = -53), 轴(BSSID = d4:5d:df:31:e4:20,RSSI = -51),轴(BSSID = d4:5d:df:31:e4:24, RSSI = -51),轴(BSSID = d4:5d:df:31:e4:1d,RSSI = -48), 轴(BSSID = d4:5d:df:31:e4:18,RSSI = -42),轴(BSSID = d4:5d:df:31:e4:1e, RSSI = -42),轴(BSSID = d4:5d:df:31:e4:1a,RSSI = -41), 轴(BSSID = d4:5d:df:31:e4:1b,RSSI = -40)]})
然后这是存储在数据库中的rmString的一个例子:
{"map":{"Label(x\u003d0, y\u003d0)":
[{"BSSID":"10:da:43:84:cb:75","RSSI":-92},
{"BSSID":"52:86:8c:2f:0f:7d","RSSI":-91},
{"BSSID":"78:f2:9e:57:0d:00","RSSI":-90},
{"BSSID":"78:f2:9e:57:0d:04","RSSI":-90},
{"BSSID":"2c:7e:81:c4:70:ed","RSSI":-89},
{"BSSID":"10:da:43:86:9b:51","RSSI":-88},
{"BSSID":"ae:8f:e0:0a:b6:d5","RSSI":-88},
{"BSSID":"40:b0:34:79:75:0f","RSSI":-88},
{"BSSID":"a4:2b:8c:d3:02:4b","RSSI":-88},
{"BSSID":"9e:8f:e0:0a:b6:d5","RSSI":-87},
{"BSSID":"ee:5d:df:92:49:28","RSSI":-87},
{"BSSID":"d4:5d:df:31:e4:1e","RSSI":-47},
{"BSSID":"d4:5d:df:31:e4:18","RSSI":-42}]}}
编辑2:
我将rmString放入JSON验证器中,它是有效的JSON,在我将其插入数据库之前和之后都将其输出。因此,由于某种原因,gson.fromJson(rmString,RadioMap :: class.java)无法将有效的json转换回我的对象。我认为这与设置RadioMap对象的方式有关。
数据类RadioMap()应该以不同的方式完成吗?
答案 0 :(得分:1)
对象图未正确反序列化,因为您使用复合对象(Label
)作为映射键。没有标准的方法将这样的地图表示为JSON数据结构。