Итак, я написал следующий kotlin код для приложения android для извлечения данных из "api.openweathermap.org/data/2.5/weather?q=london&appid=c2b58047e18bbe39e7e547e9083f4824". Данные по этой ссылке относятся к лондонскому городу. Приложение должно взять название города от пользователя и отредактировать URL "api.openweathermap.org/data/2.5/weather?q= enjCITY NAME} & appid = c2b58047e18bbe39e7e547e9083f4824" в соответствии с городом и получить JSON файл с URL. Я добавил всплывающие окна, чтобы проверить наличие ошибок. Приложение отображает всплывающее окно «всплывающее окно» после кнопки «Отправить», но не отображает никаких обновлений и не отображает какие-либо данные после вызова объекта класса 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
}
}