adsl9002 2023-03-24 10:22 采纳率: 38.5%
浏览 44

网络请求使用公共类的回调方式

#第一行代码第三版,使用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"}]
  • 写回答

1条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      问题事件

      • 修改了问题 3月25日
      • 修改了问题 3月24日
      • 创建了问题 3月24日

      悬赏问题

      • ¥20 有ASP .NET MVC做的小说阅读网站吗?
      • ¥20 beeline客户端支持ipv6地址连接hive服务
      • ¥15 香农解码的代码问题,无法输出解码结果
      • ¥15 Python操作注册表
      • ¥45 入门级别的一段VUE前端拍照像后端发送请求的代码,帮排错
      • ¥15 anaconda打开spyder后一直闪退,不知道怎么办
      • ¥15 解决迷宫问题中无法运行的问题
      • ¥15 关于aspnetcore中使用mqttnet库的entire
      • ¥15 关于#python#的问题,请各位专家解答!
      • ¥100 关于远控软件的两个问题