在SQLite数据库中将自定义对象保存为JSON

时间:2018-03-12 02:30:34

标签: android kotlin gson

我对使用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()应该以不同的方式完成吗?

1 个答案:

答案 0 :(得分:1)

对象图未正确反序列化,因为您使用复合对象(Label)作为映射键。没有标准的方法将这样的地图表示为JSON数据结构。