2017-10-16 112 views
0

在我的Android应用程序(用Kotlin编写)中,我需要将一些JSON变成一个字符串给MainObject哈希映射。这是JSON的样子:使用Gson对象的JSON到HashMap

{ 
    "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" 
     ] 
    } 
} 

我创建了几个对象来帮助解决这个问题。

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 
} 

如何将其转换为HashMap<String, MainObject>类型?我尝试使用TypeToken,如here所述,但我收到错误“期望的开始对象,但是是字符串”。

任何想法?

UPDATE

我也通过该解决方案读取JSON数据局部描述here

错误日志

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)  

更新2

实际问题我的方式有问题ding在我的本地JSON文件中。我使用的代码是这样的:

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 
} 

这给了我这些奇怪的字符,当我打印出来的JSON到控制台:

10-15 23:55:11.911 3351-3351/XXX I /系统.out: {

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

不知道为什么。

+0

请分享整个错误日志。 – Joshua

+0

更新它与错误日志 –

回答

1

我不知道为什么你有任何错误。我能够用以下代码解析JSON。

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) 
+0

嗯,有趣。感谢您为我运行该测试。这让我觉得我在JSON文件本身阅读的方式有些问题。 –

0

好的,在别人的帮助下,我发现问题不在于Gson或我的JSON或任何东西。这正是我正在将它读入记忆中的方式。我使用的代码是:

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 
} 

然而,String(buffer)默认使用UTF_8字符​​集。为了使我的工作,我需要使用UTF_16字符集。工作变更使用String(buffer, Charsets.UTF_16)