我正在开发一个 Android 应用程序,它使用 Retrofit 来调用 Render 上托管的模型。端点应该接受带有州和年份的请求,并返回包含预测降雨数据的 JSON 对象。
以下是典型 JSON 响应的示例:
{
"predicted_rainfall": {
"APR": 124.20799999999997,
"AUG": 358.282,
"DEC": 68.95199999999994,
"FEB": 27.997999999999966,
"JAN": 18.76000000000003,
"JUL": 911.7139999999999,
"JUN": 666.5559999999996,
"MAR": 44.099999999999994,
"MAY": 177.19000000000023,
"NOV": 259.6499999999997,
"OCT": 305.5620000000003,
"SEP": 296.3400000000001
},
"state": "KERALA",
"year": "1901"
}
终点是
"https://rainfallpredictionmodel.onrender.com/predict/rainfall"
。
我创建了一个 Retrofit 设置来调用此端点,但它总是失败,并显示错误“连接失败”。最初,我使用 Volley 但遇到了同样的问题,促使改用 Retrofit。
这是改造设置的代码:
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import okhttp3.OkHttpClient
import org.json.JSONObject
import java.util.concurrent.TimeUnit
class BottomSheetRainfall : BottomSheetDialogFragment() {
private val TAG = "RainfallFragment"
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_bottom_sheet_rainfall, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val submitButton = view.findViewById<Button>(R.id.submit_rainfall)
val stateNameEditText = view.findViewById<EditText>(R.id.state_name)
val yearEditText = view.findViewById<EditText>(R.id.year)
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // Increased connection timeout
.readTimeout(30, TimeUnit.SECONDS) // Increased read timeout
.writeTimeout(30, TimeUnit.SECONDS) // Increased write timeout
.build()
val retrofit = Retrofit.Builder()
.baseUrl("https://rainfallpredictionmodel.onrender.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
val rainfallService = retrofit.create(RainfallService::class.java)
submitButton.setOnClickListener {
val state = stateNameEditText.text.toString().uppercase()
val year = yearEditText.text.toString()
if (state.isNotEmpty() && year isNotEmpty()) {
val request = RainfallRequest(state, year)
rainfallService.predictRainfall(request).enqueue(object : Callback<RainfallResponse> {
override fun onResponse(
call: Call<RainfallResponse>,
response: Response<RainfallResponse>
) {
if (response.isSuccessful) {
val predictedRainfall = response.body()?.predicted_rainfall ?: emptyMap()
Toast.makeText(
requireContext(),
"Rainfall data retrieved successfully",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
requireContext(),
"Error: ${response.message()}",
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<RainfallResponse>, t: Throwable) {
Log.e(TAG, "Error during API call", t)
Toast.makeText(requireContext(), "Error: ${t.localizedMessage}", Toast.LENGTH_SHORT).show()
}
})
} else {
Toast.makeText(requireContext(), "Please enter both state and year", Toast.LENGTH_SHORT).show()
}
}
}
}
RainfallService
界面如下所示:
package com.example.safenet
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST
interface RainfallService {
@POST("predict/rainfall")
fun predictRainfall(@Body request: RainfallRequest): Call<RainfallResponse>
}
这是请求和响应的数据类:
com.example.safenet 包
数据类 RainfallRequest(val 状态: String, val 年份: String)
数据类 RainfallResponse(val Predicted_rainfall: Map
尽管如此设置,我仍然收到以下错误:“无法连接到
https://rainfallpredictionmodel.onrender.com/predict/rainfall
。” Retrofit 和 Volley 都会出现同样的错误。对于解决此问题的任何建议,我将不胜感激。
你添加了吗
<uses-permission android:name="android.permission.INTERNET" />
在 AndroidManifest 中?