使用 OkHttp 以及解析 JSON数据 和网络请求回调

 使用 OkHttp

  • 首先需要在项目中添加 OkHttp库 的依赖
dependencies {
    ......
    implementation 'com.squareup.okhttp3:okhttp:4.4.1'
}
  • 创建一个OkHttpClient实例
val client = OkHttpClient()
  • 创建一个Request对象
val request = Request.Builder().url("https://www.baidu.com").build()
  • 调用 OkHttpClient 的 newCall() 方法来创建一个Call对象,并调用它的 execute() 方法来发送请求,并获取从服务器返回的数据。
val response = client.newCall(request).execute()
  • 该response对象即为服务器返回的数据,可进行查看
response.body?.string()

 发起POST请求

  • 构建一个 Request Body 对象来存放待提交数据
val requestBody =  FormBody.Builder().add("username", "admin").add("password", "123456").build()
  • 在Request.Builder中调用  post()  方法,并将 Request Body 对象传入
val request = Request.Builder().url("https://www.baidu.com").post(requestBody).build()

全部代码如下:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendRequestBtn = findViewById(R.id.sendRequestBtn)
        responseText = findViewById(R.id.responseText)

        sendRequestBtn.setOnClickListener {
            sendRequestWithOkHttp()
        }
    }

    private fun sendRequestWithOkHttp() {
        thread {
            try {
                val client = OkHttpClient()
                val requestBody =
                    FormBody.Builder().add("username", "admin").add("password", "123456").build()
                val request = Request.Builder().url("https://www.baidu.com").post(requestBody).build()
                val response = client.newCall(request).execute()
                val responseData = response.body?.string()
                if (responseData != null) showResponse(responseData)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

解析 JSON数据

(一) 使用JSONObject

  • 首先,调用OkHttp从网页获取数据
    private fun sendRequestWithOkHttp() {
        thread {
            try {
                //创建一个OkHttpClient实例
                val client = OkHttpClient()
                //创建要请求的对象
                val request = Request.Builder().url("").build()
                //调用实例的 Call 方法来发出请求,同时请求数据
                val response = client.newCall(request).execute()
                //获取请求的数据
                val responseData = response.body?.string()
                
                //当请求的数据不为空时,进行对应格式数据解析
                if (responseData != null) {
                    parseJSONWithJSONObject(responseData)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
  • 通过JSONObject 来进行JSON格式数据解析,方法实现如下:
    private fun parseJSONWithJSONObject(jsonData: String) {
        try {
            //根据获取的数据类型,来创建对应的数据结构进行数据保存
            val jsonArray = JSONArray(jsonData)
            for (i in 0 until jsonArray.length()) {
                val jsonObject = jsonArray.getJSONObject(i)
                val id = jsonObject.getString("id")
                val version = jsonObject.getString("version")
                val name = jsonObject.getString("name")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

根据获取的数据类型,来创建对应的数据结构进行数据保存。然后遍历数据结构,获取想要的数据。本例子使用的JSON数据如下所示:

[{"id":"5","version":"5.5","name":"Clash of Clans"},
{"id":"6","version":"7.0","name":"Boom Beach"},
{"id":"7","version":"3.5","name":"Clash Royale"}]

(二) 使用GSON 

Google提供的GSON开源库可以让解析JSON数据的工作简单到让你不敢想象的地步!

如果想要使用GSON需要首先添加GSON依赖库,GSON的强大之处在于将一段JSON格式的字符串自动映射成一个对象,从而不需要手动编写代码进行解析!!!!!

  • 添加GSON依赖库
dependencies {
    ...
    implementation 'com.squareup.okhttp3:okhttp:4.4.1'
    implementation 'com.google.code.gson:gson:2.8.6'
}
  • 如果一段JSON格式数据为
{"name":"Tom","age":20}

可以定义一个Person类,并加入 name 和 age 两个字段,然后调用 GSON 的 fromJson() 就可以自动解析成一个Person对象了。       

//需要先创建一个Gson实例
val gson = Gson()
val person = gson.fromJson(responseData, Person::class.java)

需要先创建一个Gson实例,然后调用 fromJson() .

  • 如果一段JSON格式数据为
[{"name":"Tom","age":20}, {"name":"Jack","age":25}, {"name":"Lily","age":22}]

需要借助 TypeToken 将期望解析成的数据类型传入 fromJson() 方法中,如下所示:

val typeOf = object : TypeToken<List<Person>>() {}.type
val people = gson.fromJson<List<Person>>(responseData,typeOf)

示例代码如下,新建一个App类,将JSON格式存储为App对象:

    private fun parseJSONWithGson(jsonData: String) {
        try {
            val gson = Gson()
            val typeOf = object : TypeToken<List<App>>() {}.type
            val appList = gson.fromJson<List<App>>(jsonData, typeOf)
            for (app in appList) {
                //业务逻辑
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

网络请求回调的实现方式 

一个项目中可能用到很多网络请求,如果每一次都需要编写相同代码,非常差劲。

通常情况下,将这些通用的网络操作提取到一个公共的类中,当需要网络请求时,调用方法即可。

需要网络请求回调的原因:

网络请求通常属于耗时操作,而sendHttpRequest()方法的内部并没有开启线程。如果我们在sendHttpRequest()方法中开启一个线程来发起HTTP请求,服务器响应的数据是无法进行返回的。这是由于所有的耗时逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器还没来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。

 使用HTTP来进行网络请求

需要重新定义一个接口,进行回调。

interface HttpCallbackListener {
    fun onFinish(response: String)
    fun onError(e:Exception)
}
object HttpUtil {
    
    ......

    fun sendHttpRequest(address: String, listener: HttpCallbackListener) {
        thread {
            var connection: HttpURLConnection? = null
            try {
                val 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()
                // 回调onError()方法
                listener.onError(e)
            } finally {
                connection?.disconnect()
            }
        }
    }
}

调用时还需要将 HttpCallbackListener 的实例传入,然后重写接口中的两个方法。

    private fun sendRequestWithHttpURLConnection() {
        val address = "https://www.baidu.com"
        HttpUtil.sendHttpRequest(address, object : HttpCallbackListener {
            override fun onFinish(response: String) {
                //从服务器返回的内容
                showResponse(response)
            }

            override fun onError(e: Exception) {
                //对异常情况进行处理
            }
        })
    }

    private fun showResponse(response: String) {
        responseText.text = response
    }

 调用时:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendRequestBtn = findViewById(R.id.sendRequestBtn)
        responseText = findViewById(R.id.responseText)

        sendRequestBtn.setOnClickListener {
            sendRequestWithHttpURLConnection()
//            sendRequestWithOkHttp()
        }
    }

 使用OkHttp来进行网络请求

在公共类中定义如下:

object HttpUtil {
    fun sendOkHttpRequest(address: String, callback: okhttp3.Callback) {
        var connection: HttpURLConnection? = null
        try {
            val client = OkHttpClient()
            val request = Request.Builder().url(address).build()
            client.newCall(request).enqueue(callback)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    ......
}

sendOkHttpRequest()方法中有一个okhttp3.Callback参数,这个是OkHttp库中自带的回调接口,类似于我们刚才自己编写的HttpCallbackListener。然后在client.newCall()之后没有像之前那样一直调用execute()方法,而是调用了一个enqueue()方法,并把okhttp3.Callback参数传入。

OkHttp在 enqueue() 方法的内部已经帮我们开好子线程了,

    private fun sendRequestWithOkHttp() {

        val address = "https://www.baidu.com"
        HttpUtil.sendOkHttpRequest(address, object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                //对异常情况进行处理
            }

            override fun onResponse(call: Call, response: Response) {
                //得到从服务器返回的具体内容
                val responseData = response.body?.string()
            }

        })
    }

调用时:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sendRequestBtn = findViewById(R.id.sendRequestBtn)
        responseText = findViewById(R.id.responseText)

        sendRequestBtn.setOnClickListener {
//            sendRequestWithHttpURLConnection()
            sendRequestWithOkHttp()
        }
    }

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在安卓开发中,可以使用OkHttp库来进行网络请求操作,并使用第三方库(如Gson)来解析JSON数据。以下是一个简单的示例代码,展示了如何使用OkHttp和Gson来解析JSON数据: 首先,在你的项目中添加OkHttp和Gson的依赖。在app的build.gradle文件中添加以下代码: ```groovy dependencies { // OkHttp implementation 'com.squareup.okhttp3:okhttp:4.9.1' // Gson implementation 'com.google.code.gson:gson:2.8.7' } ``` 接下来,创建一个网络请求工具类,例如 `HttpUtil.java`,其中包含一个方法用于发送网络请求解析JSON数据: ```java import com.google.gson.Gson; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient;import okhttp3.Request; import okhttp3.Response; import java.io.IOException; public class HttpUtil { private static final OkHttpClient client = new OkHttpClient(); private static final Gson gson = new Gson(); public static void sendHttpRequest(String url, final HttpCallback callback) { Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { callback.onError(e.getMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { String responseData = response.body().string(); Object result = gson.fromJson(responseData, Object.class); // 将JSON数据解析为自定义的对象类型,这里使用了Object作为示例 callback.onSuccess(result); } }); } } ``` 上述代码中,`sendHttpRequest` 方法用于发送GET请求并处理响应。调用该方法时,需要传入请求的URL和一个自定义的 `HttpCallback` 接口回调。 接下来,创建一个回调接口 `HttpCallback.java`: ```java public interface HttpCallback { void onSuccess(Object response); // 请求成功的回调方法,可根据自己的需求修改参数类型 void onError(String error); // 请求失败的回调方法 } ``` 现在,你可以在你的Activity或Fragment中使用 `HttpUtil` 类来进行网络请求解析JSON数据。以下是一个简单的示例: ```java String url = "http://your-api-url.com/data"; // 替换为你自己的API接口地址 HttpUtil.sendHttpRequest(url, new HttpCallback() { @Override public void onSuccess(Object response) { // 解析成功 // 在这里处理解析后的JSON数据 } @Override public void onError(String error) { // 请求失败 // 在这里处理错误情况 } }); ``` 在 `onSuccess` 方法中,你可以对返回的 `response` 对象进行进一步处理,根据实际情况将其转换为你自定义的数据结构。 以上就是使用OkHttp和Gson库进行JSON解析的基本示例。当然,具体的实现方式可以根据你的项目需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值