1、前言
本文分别介绍使用HttpURLConnection和OkHttp进行简单的网络请求,同时介绍如何进行JSON格式数据的解析。
首先既然要发送网络请求获取JSON数据,就得有服务器提供的接口地址,这里采用一个最简单的方式来搭建服务器。
开启你的Tomcat服务器,然后找到存放tomcat的文件夹,在webapps文件夹下的ROOT里面创建一个student_data.json的文件,文件内容写一段Josn格式的数据。例如:
[{"id" : "101" , "name" : "张三" , "classNum" : "1"},
{"id" : "102" , "name" : "李四" , "classNum" : "2"},
{"id" : "103" , "name" : "王五" , "classNum" : "2"}]
(存放地址 D:\tomcat\webapps\ROOT)
然后在浏览器输入地址http://localhost:9090/student_data.json (修改成你自己的端口号),看到这个页面就行了。
同时在你手机模拟器的浏览器上也要能访问到这个页面,访问地址是这样的:http://10.0.2.2:9090/student_data.json
或者是:http://你电脑的IP地址
:9090/student_data.json
如果看不到这个页面,等下要写的网络请求案例也是失败的。
2、开始
我会介绍两种网络请求方式和两种数据解析方法。
编写一个单例类HttpUtil来包含这两种请求方法。
声明网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
2.1 使用HttpURLConnection网络请求、使用JSONObject数据解析
object HttpUtil {
//使用HttpURLConnection
fun sendHttpRequest(address: String, listener: HttpCallbackListener) {
thread {
var connection: HttpURLConnection? = null
try {
val response = StringBuilder()
//创建URL对象,传入网络地址
val url = URL(address)
//通过openConnection()方法获取HttpURLConnection实例
connection = url.openConnection() as HttpURLConnection
//进行一些配置,如消息头等
connection.connectTimeout = 8000//连接超时毫秒数
connection.readTimeout = 8000//读取超时毫秒数
//通过connection.getInputStream()方法获取服务器返回的输入流
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()
}
}
}
}
回调接口
interface HttpCallbackListener {
fun onFinish(response: String)
fun onError(e: Exception)
}
在MainActivity.kt中发起请求
// 使用HttpURLConnection发送请求
sendRequestBtn.setOnClickListener {
// 调用HttpUtil类写好的sendHttpRequest()方法,
// 传入地址和回调监听(该用于回调的接口类是自己编写的,不是原本有的)
HttpUtil.sendHttpRequest("http://192.168.1.113:9090/student_data.json",object : HttpCallbackListener{
override fun onFinish(response: String) {
//使用JSONObject解析服务器返回的JSON数据
parseJSONWithJSONObject(response)
}
override fun onError(e: Exception) {
//请求出错
Log.d(TAG,"ERROR:$e")
}
})
}
通过使用JSONObject进行数据解析
// JSONObject解析
private fun parseJSONWithJSONObject(jsonData: String) {
try {
// 由于服务器返回的是一个JSON数组,所以先将数据传入到JSONArray对象中
val jsonArray = JSONArray(jsonData)
// 循环遍历得到每一个JSONObject对象
for(i in 0 until jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(i)
//获取具体数据
val id = jsonObject.getString("id")
val name = jsonObject.getString("name")
val classNum = jsonObject.getString("classNum")
Log.d(TAG,"id is $id,name is $name,classNum is $classNum");
}
}catch (e: Exception){
e.printStackTrace()
}
}
2.2 使用Okhttp网络请求、使用GSON数据解析
添加依赖:
implementation 'com.squareup.okhttp3:okhttp:3.3.1'
implementation 'com.google.code.gson:gson:2.8.5'
//使用OkHttp
fun sendOkHttpRequest(address: String, callback: okhttp3.Callback){
//创建OkHttpClient实例
val client = OkHttpClient()
// 创建Request对象,并进行网络地址url的设置等操作
val request = Request.Builder()
.url(address)
.build()
// 调用OkHttpClient的newCall()方法创建Call对象
// 并调用它的enqueue()方法发送请求和获取服务器返回的数据
client.newCall(request).enqueue(callback)
}
发送请求
sendOkhttpRequestBtn.setOnClickListener {
HttpUtil.sendOkHttpRequest("http://192.168.1.113:9090/student_data.json",object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
//请求出错
Log.d(TAG,"ERROR:$e")
}
override fun onResponse(call: Call?, response: Response?) {
val jsonData = response?.body()?.string()
if (jsonData != null) {
//使用Gson解析服务器返回的JSON数据
parseJSONWithGSON(jsonData)
}
}
})
}
使用GSON进行数据解析
// GSON解析
// GSON可将一段JSON格式的字符串自动映射成一个对象
private fun parseJSONWithGSON(jsonData: String) {
val gson = Gson()
//设置要得到的数据格式
val typeOf = object : TypeToken<List<Student>>() {}.type
val stuList = gson.fromJson<List<Student>>(jsonData,typeOf)
for (student in stuList){
Log.d(TAG,"id is ${student.id},name is ${student.name},classNum is ${student.classNum}")
}
}
Student类
class Student(val id: String, val name: String, val classNum: String)