#第一行代码第三版,使用Google提供的gson解析json数据。之后的小节说应该将这些通用的网络操作提取到一个公共类了,并提供一个通用方法,挡要发起网络请求的时候,只需要简单的调用一下这个方法即可。比如
package com.example.networktest
import okhttp3.OkHttpClient
import okhttp3.Request
object HttpUtil {
fun sendOkHttpRequest(address: String, callback: okhttp3.Callback) {
val client = OkHttpClient()
val request = Request.Builder()
.url(address)
.build()
client.newCall(request).enqueue(callback)
}
}
#然后调用sendOKHttpRequest()方法的时候就可以这么写
HttpUtil.sendOkHttpRequest(address, object : Callback {
override fun onResponse(call: Call, response: Response) {
//得到服务器返回的具体内容
val responseData = response.body?.string()
}
override fun onFailure(call: Call, e: IOException) {
// 在这里对异常情况进行处理
}
})
#我尝试这么写,但不对
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendBtn: Button = findViewById(R.id.sendRequestBtn)
sendBtn.setOnClickListener {
val address = "http://10.0.2.2/get_data.json"
HttpUtil.sendOkHttpRequest(address, object : Callback {
override fun onResponse(call: Call, response: Response) {
val responseData = response.body?.string()
val gson = Gson()
val typeOf = object : TypeToken<List<App>>() {}.type
val appList = gson.fromJson<List<App>>(responseData, typeOf)
for (app in appList) {
Log.d("MainActivity", "id is ${app.id}")
Log.d("MainActivity", "name is ${app.name}")
Log.d("MainActivity", "version is ${app.version}")
}
}
override fun onFailure(call: Call, e: IOException) {
TODO("Not yet implemented")
}
})
}
}
}
#那么要用以上方法,我该怎么修改呢,
#MainActivity kt
package com.example.networktest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import okhttp3.*
import kotlin.concurrent.thread
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendBtn: Button = findViewById(R.id.sendRequestBtn)
sendBtn.setOnClickListener {
sendRequestWithOkHttp()
}
}
//使用OkHttp发起网络请求
private fun sendRequestWithOkHttp() {
thread {
try {
val client = OkHttpClient()
val request = Request.Builder()
.url("http://10.0.2.2/get_data.json")
.build()
val response = client.newCall(request).execute()
val responseData = response.body?.string()
if (responseData != null) {
parseJSONWithJSON(responseData)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
private fun parseJSONWithJSON(jsonData: String) {
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 is ${app.id}")
Log.d("MainActivity", "name is ${app.name}")
Log.d("MainActivity", "version is ${app.version}")
}
}
}
#App.kt
package com.example.networktest
// 新建一个类,并加入需要的字段
class App (val id: String, val name: String, val version: String)
#HttpUtil.kt
package com.example.networktest
import okhttp3.OkHttpClient
import okhttp3.Request
object HttpUtil {
fun sendOkHttpRequest(address: String, callback: okhttp3.Callback) {
val client = OkHttpClient()
val request = Request.Builder()
.url(address)
.build()
client.newCall(request).enqueue(callback)
}
}
#activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/sendRequestBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/send_request"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintVertical_weight="1"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/sendRequestBtn"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:id="@+id/responseText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
#AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.NetworkTest"
android:networkSecurityConfig="@xml/network_config"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
#network_config.xml
<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
<base-config cleartextTrafficPermitted= "true">
<trust-anchors>
<certificates src = "system" />
</trust-anchors>
</base-config>
</network-security-config>
#OKhttp和gson依赖库
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("com.google.code.gson:gson:2.8.9")
#get_data.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"}]