JSON a HashMap con objects usando Gson

En mi aplicación de Android (escrita en Kotlin), necesito convertir algunos JSON en una cadena para MainObject hash map. Así es como se ve el JSON:

{ "a": { "name": "A", "some_int": "2", "some_string": "string", "some_bool": false, "some_string_arr": [ "str1", "str2" ], "sub_obj_arr": [ { "obj_name": "d", "some_obj_string": "s" } ] }, "b": { "name": "B", "some_int": "4", "some_string": "string", "some_bool": false, "some_string_arr": [ "str5", "str6" ] } } 

Creé un par de objects para ayudar con esto.

 class MainObject { @SerializedName("name") val name: String? = null @SerializedName("some_int") val someInt: Int? = null @SerializedName("some_string") val someString: String? = null @SerializedName("some_bool") val someBool: Boolean = false @SerializedName("some_string_arr") val someStringArr: List<String>? = null @SerializedName("sub_obj_arr") val someObjArr: List<SubObject>? = null } class SubObject { @SerializedName("obj_name") val objName: String? = null @SerializedName("some_obj_string") val someObjString: String? = null } 

¿Cómo convierto esto en un tipo de HashMap<String, MainObject> ? Intenté usar un TypeToken como se describe aquí , pero recibí el error "expected begin object but was string".

¿Algunas ideas?

ACTUALIZAR

También estoy leyendo los datos JSON localmente a través de la solución que se describe aquí

Registro de errores

 10-15 20:06:42.771 10328-10328/xxx E/AndroidRuntime: FATAL EXCEPTION: main Process: xxx, PID: 10328 java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ at com.google.gson.Gson.fromJson(Gson.java:900) at com.google.gson.Gson.fromJson(Gson.java:853) at com.google.gson.Gson.fromJson(Gson.java:802) at xxx.onCreate(BottomNavigation.kt:48) at android.app.Activity.performCreate(Activity.java:6975) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:183) at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145) at com.google.gson.Gson.fromJson(Gson.java:888) at com.google.gson.Gson.fromJson(Gson.java:853) at com.google.gson.Gson.fromJson(Gson.java:802) at xxx.onCreate(BottomNavigation.kt:48) at android.app.Activity.performCreate(Activity.java:6975) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

Actualización 2

El problema real es algo malo con la forma en que estoy leyendo en mi file JSON local. El código que uso es este:

 val input = this.resources.openRawResource(R.raw.json) val json = try { val size = input.available() val buffer = ByteArray(size) input.read(buffer) input.close() String(buffer) } catch (ex: IOException) { ex.printStackTrace() null } 

Lo que me da estos caracteres extraños cuando imprimo el JSON en la console:

10-15 23: 55: 11.911 3351-3351 / xxx I / System.out: {

10-15 23: 55: 11.911 3351-3351 / xxx I / System.out: " a " : {

Sin embargo, por qué.

No sé por qué tienes algún error. Puedo analizar el JSON con el siguiente código.

 val gson = GsonBuilder().create() val type = object:TypeToken<Map<String, MainObject>>(){}.type val result = gson.fromJson<Map<String, MainObject>>("{ \"a\": { \"name\": \"A\", \"some_int\": \"2\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str1\", \"str2\" ], \"sub_obj_arr\": [ { \"obj_name\": \"d\", \"some_obj_string\": \"s\" } ] }, \"b\": { \"name\": \"B\", \"some_int\": \"4\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str5\", \"str6\" ] } }", type) 

De acuerdo, con la ayuda de otros descubrí que el problema no era con Gson o mi JSON ni nada. Fue en la forma en que lo estaba leyendo en la memory. El código que estaba usando era:

 val input = this.resources.openRawResource(R.raw.json) val json = try { val size = input.available() val buffer = ByteArray(size) input.read(buffer) input.close() String(buffer) } catch (ex: IOException) { ex.printStackTrace() null } 

Sin embargo, String(buffer) pnetworkingeterminado a usar UTF_8 charset. Para que el mío funcione, necesitaba usar un juego de caracteres UTF_16. El cambio de trabajo estaba usando String(buffer, Charsets.UTF_16) .

  • Kotlin: cómo henetworkingar del suscriptor de RxJava
  • jackson-dataformat-csv no ignora las properties desconocidas
  • ¿Cómo hacer reference a la class interna anónima en Kotlin?
  • ¿Cómo obtengo el resultado de una function de pepino?
  • Cómo saber cuándo el fragment no está visible en un Navegador
  • ¿Cómo puedo hacer que el parámetro param sea mutable en Kotlin?
  • Cómo modificar la variable de instancia de AsyncTask por separado
  • Kotlin, NoSuchMethodError en el operador get
  • ¿Cómo se pueden agregar methods estáticos a las classs de Java en Kotlin?
  • problemas del comstackdor de Kotlin para la class no resuelta
  • Inferir solo algunos parameters de tipo en Kotlin