2017-10-16 105 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)