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) .

  • Dagger 2 no genera la class de componente (Android, Kotlin)
  • ¿Cómo burlarse de los methods estáticos en Kotlin?
  • Cómo convertir Long to Int en Kotlin?
  • ¿Cómo crear un JSONObject desde String en Kotlin?
  • Convertir matriz en list en Kotlin
  • Clase de datos que henetworkinga de la class Java
  • Kotlin: itera sobre los componentes del object
  • No se puede importar un package generado swig
  • Cómo agregar varias instrucciones dentro de una instrucción when en kotlin
  • RxJava, ¿Qué pasó si no llamo a disponer?
  • Broadcast Reciver en kotlin