android - 有没有办法同步运行 Okhttps 请求?
问题描述
所以我正在尝试一个应用程序,我正在发出一个 okhttp 请求。我发现这个请求任务是在它自己的线程上进行的,这会导致异步行为。
在下方,您会看到我的函数,它从 API 获取数据,以及 onCreateView 函数,我在其中调用 fetchData()。
@Throws(IOException::class)
fun fetchData() {
val client = OkHttpClient()
val request: Request = Request.Builder()
.url("https://www.themealdb.com/api/json/v1/1/search.php?f=a")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
call.cancel()
}
@Throws(IOException::class)
override fun onResponse(call: Call, response: Response) {
val responseString = U.formatJson(response.body?.string())
val meals = Gson().fromJson(responseString, Meals::class.java)
Log.d(TAG, "First")
}
})
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
fetchData()
Log.d(TAG, "second")
return inflater.inflate(R.layout.fragment_home, container, false)
}
所以我把这些日志放在这里看看,哪个 Log 被首先调用,并且由于 fetchData() 是异步的,很明显 onCreateView() 中的 Log.d(TAG, "second") 被首先调用。因此,如果我尝试使用下面请求的数据,我会得到 null,因为请求尚未完成。这就是我的问题。调用函数后我需要使用请求的数据。
有什么解决方案可以让我以某种方式同步进行 fetchData() 但不阻塞主线程?
解决方案
您不能在主线程上运行网络请求。它必须是异步的。只是猜测你在做什么,我会在你的 fetch 函数中添加一个回调并像这样使用它。
fun fetchData(callback: (Meals?) -> Unit) {
val client = OkHttpClient()
val request: Request = Request.Builder()
.url("https://www.themealdb.com/api/json/v1/1/search.php?f=a")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
call.cancel()
callback(null)
}
@Throws(IOException::class)
override fun onResponse(call: Call, response: Response) {
val responseString = U.formatJson(response.body?.string())
val meals = Gson().fromJson(responseString, Meals::class.java)
callback(meals)
}
})
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
fetchData { meals ->
if (meals == null)
showErrorMessage()
else
updateSomeListAdapterWithMeals(meals)
}
return inflater.inflate(R.layout.fragment_home, container, false)
}
fetchData
由于回调将在稍后触发,因此在膨胀视图之前调用并不重要。
推荐阅读
- json - Flutter:我对这个集合的每个元素在 JSON 数据的迭代顺序中都有问题
- tinymce - TinyMCE 5:除非图像后面有文字,否则图像不会显示
- r - R函数来识别不同列和行之间的重复
- binary-decision-diagram - 如何区分二元决策图的正整数和负整数
- typescript - 如何使用类型参数调用 const 函数?
- android - Firebase Firestore 避免在通过片段快速来回切换时多次检索相同的数据
- xcode - 为什么 Xcode 在 Build/Run-time 的 Big Sur 更新中无法识别 iPhone?
- c# - 通过 Rest api 上传到 Azure devops 的附件未打开
- flutter - 如何找到 Dart 文件的 pubspec yaml 来修复 null 安全问题?
- python-3.x - “calculate_bartlett_sphericity”测试输出 nan 值