第一行代碼 第三版 第11章網絡技術 11.4 解析JSON格式數據 以及回調的實現

11.4 解析JSON格式數據

準備數據:
在這裏插入圖片描述

11.4.1 使用JSONObject

JSONObject這是官方提供的

由於在服務器中定義的是一個JSON數組。
將返回的數據傳入一個JSONArray對象中;
循壞遍歷JSONArray對象,從中取出的每一個元素都是一個JSONObject對象 ;
從JSONObject對象中取出相應的數據。

private fun parseJSONWithJSONObject(jsonData:String){
        try {
            val jsonArray = JSONArray(jsonData)  //將返回的數據傳入一個JSONArray對象中
            for (i in 0 until jsonArray.length()){
                val jsonObject = jsonArray.getJSONObject(i)
                val id = jsonObject.getString("id")
                val name = jsonObject.getString("name")
                val version = jsonObject.getString("version")
                Log.d("MainActivity","id = $id")
                Log.d("MainActivity","name = $name")
                Log.d("MainActivity","version = $version")
            }
        }catch (e:Exception){
            e.printStackTrace()
        }
    }

14.4.2 使用GSON

GSON是Google 提供的開源庫,用於解析JSON數據;附上該開源庫的項目地址https://github.com/google/gson

要使用的話 ,需要添加GSON庫的依賴。app/build.gradle 中的dependencies 閉包中添加。
在這裏插入圖片描述
GSON 庫的強大之處在於可以將一段JSON格式的字符串自動映射成一個對象。
處理{"name":"Tom","age":20}這樣的語句,需要創建一個類與之數據對應:

class XXX(val name:String ,val age:Int) {
}
//然後在需要的地方直接調用下面的代碼
val gson =Gson()
 val x = gson.fromJson(jsonData,XXX::class.java)

針對JSON數組 還需要使用TypeToken 將期望解析成的數據類型傳入fromJson() 方法中,

class App(val id :String,val name :String ,val version :String) {}//先建立與數據對應的類

private fun parseJSONWithGSON(jsonData: String){
	//下面的代碼就是用處理JSON數組的方式
        val gson=Gson()
        val typeOf = object :TypeToken<List<App>>(){}.type
        val appList = gson.fromJson<List<App>>(jsonData,typeOf)
        for (app in appList){
            Log.d("MainActivity","id = ${app.id}")
            Log.d("MainActivity","name =${app.name}")
            Log.d("MainActivity","version = ${app.version}")
        }
    }

11.5 網絡請求回調的實現方式

網絡請求一般是耗時操作。
回調機制的使用:
在接口中定義一些方法,然後在對應的函數中傳入該接口,最後在這個方法中調用接口參數的方法。

interface HttpCallbackListener {
    fun onFinish(response: String)//當服務器成功響應我們請求是調用
    fun onError(e:Exception)// 當網絡操作出現錯誤的時候調用
}
//在HttpUtil 類中
fun sendHttpRequest(address: String ,listener: HttpCallbackListener){
        thread {
            var  connection :HttpURLConnection ?=null
            try{
                var response = StringBuilder()
                val url = URL(address)
                connection = url.openConnection() as HttpURLConnection
                connection.connectTimeout=8000
                connection.readTimeout = 8000
                val input =connection.inputStream
                val reader=BufferedReader(InputStreamReader(input))
                reader.use {
                    reader.forEachLine {
                        response.append(it)
                    }
                }
                //回調onFinish()方法
                listener.onFinish(response.toString())
            }catch (e:Exception){
                e.printStackTrace()
                //回調noError()方法
                listener.onError(e)
            }finally {
                connection?.disconnect()
            }
        }
    }

調用上面的方法

sendRequestBtn.setOnClickListener {
            //sendRequestWithOkHttp()
            HttpUtil.sendHttpRequest("http://10.0.2.2/get_data.json",
                object : HttpCallbackListener {
                    override fun onFinish(response: String) {
                        parseJSONWithGSON(response)
                    }

                    override fun onError(e: Exception) {

                    }
                })
        }

具體的寫法可以參考第一行代碼第三版P448。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章