android - Kotlin - AsyncTask 不会从 API 链接获取 JSON 数据,也不会在应用程序中显示它
问题描述
因此,我为 android 应用程序编写了以下 kotlin 代码,以从“ api.openweathermap.org/data/2.5/weather?q=london&appid=c2b58047e18bbe39e7e547e9083f4824 ”中获取数据。此链接中的数据是伦敦市的数据。应用程序应该从用户那里获取城市名称并根据城市编辑 url "api.openweathermap.org/data/2.5/weather?q= {CITY NAME} &appid=c2b58047e18bbe39e7e547e9083f4824" 并从 URL 获取 JSON 文件。我添加了 Toast 弹出窗口来检查错误。应用程序在提交按钮后显示 Toast 弹出,但在调用 AsyncTask 类对象后不显示任何更新或显示任何数据。
TLDR:应用程序不会获取 JSON 数据,也不会在调用 MyAsyncTask 后显示任何更新,此时它应该显示城市的温度。
这是代码:
package com.awesome.mystartup
import android.content.Context
import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import kotlin.Exception
class MainActivity : AppCompatActivity() {
var city:String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buSubmit.setOnClickListener{
Toast.makeText(applicationContext, "Button clicked",Toast.LENGTH_SHORT).show()
city = tvCityName.text.toString().toLowerCase()
Toast.makeText(applicationContext, "city:"+city,Toast.LENGTH_SHORT).show()
val tempUrl = "api.openweathermap.org/data/2.5/weather?q="+city+"&appid=c2b58047e18bbe39e7e547e9083f4824"
**//Following Toast is the last Toast displayed**
Toast.makeText(applicationContext, tempUrl,Toast.LENGTH_LONG).show()
**MyAsyncTask().execute(tempUrl)**
}
}
inner class MyAsyncTask:AsyncTask<String,String,String>(){
override fun onPreExecute() {
//Fired before task is started
super.onPreExecute()
}
override fun doInBackground(vararg params: String?): String {
//Get HTTP Call
//UI can't access this as it's in background.
//To make sure UI shows it, call publishProgress(string)
try {
val url = URL(params[0]) // Params is kind of an array. [0] element has url
val urlConnect = url.openConnection() as HttpURLConnection
urlConnect.connectTimeout = 7000 // Wait for 7 seconds for result, if not received, throw exception
var inString = ConvertStreamToString(urlConnect.inputStream)
publishProgress(inString)
}
catch (ex:Exception){
// Toast.makeText(applicationContext, "Error in doInBackground",Toast.LENGTH_SHORT).show()
}
return ""
}
override fun onProgressUpdate(vararg values: String?) {
super.onProgressUpdate(*values)
try {
//Convert string to JSON
// Toast.makeText(applicationContext, "Progress running",Toast.LENGTH_SHORT).show()
var json = JSONObject(values[0])
val main = json.getJSONObject("main")
val temp = main.getString("temp")
var tempFloat = temp.toFloat()
tvShowTemp.text = "Temperature of the "+city+" is: "+tempFloat
}catch (ex:Exception){
// Toast.makeText(applicationContext, "Error in onProgressUpdate",Toast.LENGTH_SHORT).show()
}
}
override fun onPostExecute(result: String?) {
//fired after task is executed
super.onPostExecute(result)
}
}
//To convert input stream to String, following function is used
fun ConvertStreamToString(inputstream:InputStream):String{
//Take the input inputstream and convert it to InputStreamReader. Then convert that to BufferedReader and store it
val bufferReader = BufferedReader(InputStreamReader(inputstream))
var line:String
var allString = ""
try {
do {
line = bufferReader.readLine()
if (line != null) {
allString += line
}
} while (line != null)
} catch (ex:Exception){
// Toast.makeText(applicationContext, "Error in ConvertStreamToString",Toast.LENGTH_SHORT).show()
}
return allString
}
}
解决方案
推荐阅读
- android - 我正在尝试通过单击当前 RecyclerView 中的按钮来加载 RecyclerView
- python - IMAPLIB“初始值必须是 str 或 none,而不是字节”错误
- javascript - PHP 无法与 html、js/jquery 和 ajax 一起正常工作
- version - Anylogic 将 ALP 从版本 8.3.2 转换为 7.1.2
- oracle - 如何在表 1 中显示每年的记录,然后将计算值自动关联到第二个表中?
- html - 如果我缩小页面,我的网页不会居中,有什么提示吗?
- javascript - 在电子事件处理程序中执行 JavaScript 方法
- java - 如何将特定数字分配给特定字母?
- python - 如何根据python中的字典键获取唯一数据
- ios - Xcode 失去与 iPad 的连接