Класс не возвращает объект MutableMap
Я использовал Kotlin, чтобы создать базовое приложение-конвертер валют с API. Чтобы загрузить информацию, я создал новый класс DownloadTaskClass, расширяющий устаревший класс AsyncTask (я не изучал другие классы пакета java.util.concurrent).
DownloadTaskClass содержит метод для возврата MutableMap в MainActivity. Однако я не могу понять, почему этот метод не возвращает объект MutableMap. Вот классы.
Скачать TaskClass.kt
package com.example.kotlincurrency
import android.os.AsyncTask
import org.json.JSONObject
import java.io.InputStream
import java.io.InputStreamReader
import java.lang.Exception
import java.net.HttpURLConnection
import java.net.URL
class DownloadTaskClass: AsyncTask<String, Void, String>() {
private var data: Int = 0
private var result: String = ""
private var mutableMap: MutableMap<String, Any> = mutableMapOf()
private lateinit var url: URL
private lateinit var inputStream: InputStream
private lateinit var inputStreamReader: InputStreamReader
private lateinit var httpURLConnection: HttpURLConnection
override fun doInBackground(vararg urls: String): String? {
url = URL(urls[0])
httpURLConnection = url.openConnection() as HttpURLConnection
inputStream = httpURLConnection.inputStream
inputStreamReader = InputStreamReader(inputStream)
data = inputStreamReader.read()
while (data != -1){
val current: Char = data.toChar()
result += current
data = inputStreamReader.read()
}
return result
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
try {
val jsonObject = JSONObject(result)
mutableMap["date"] = jsonObject.getString("date")
val rates: String = jsonObject.getString("rates")
val currencyJSONObject = JSONObject(rates)
mutableMap["USD"] = currencyJSONObject.getString("USD")
mutableMap["GBP"] = currencyJSONObject.getString("GBP")
mutableMap["EUR"] = currencyJSONObject.getString("EUR")
mutableMap["CHF"] = currencyJSONObject.getString("CHF")
mutableMap["SEK"] = currencyJSONObject.getString("SEK")
mutableMap["CAD"] = currencyJSONObject.getString("CAD")
}
catch (e: Exception){
e.printStackTrace()
}
}
fun returnMapMethod(): MutableMap<String, Any>{
return mutableMap
}
}
MainActivity.kt
package com.example.kotlincurrency
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.appcompat.app.ActionBar
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setActionBar()
downloadInitInfo()
}
private fun setActionBar() {
supportActionBar!!.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar!!.setDisplayShowCustomEnabled(true)
supportActionBar!!.setCustomView(R.layout.layout_action_bar)
}
private fun downloadInitInfo(){
val downloadTaskClass = DownloadTaskClass()
downloadTaskClass.execute("https://api.exchangeratesapi.io/latest?base=INR")
println(downloadTaskClass.returnMapMethod())
}
}
1 ответ
Вы делаете асинхронный запрос в doInBackground()
метод, это может занять некоторое время, прежде чем onPostExecute()
называется и mutableMap
заполнен данными. Когда ты звонишьreturnMapMethod()
метод mutableMap
объект еще не заполнен данными. Вам нужно использовать какой-нибудь слушатель, чтобы получать уведомления о загрузке данных.
Вот пример использования LiveData
для наблюдения данных:
class DownloadTaskClass: AsyncTask<String, Void, String>() {
private var data: MutableLiveData<MutableMap<String, Any>> = MutableLiveData()
// ...
override fun onPostExecute(result: String?) {
// ...
data.value = mutableMap
}
fun returnMapMethod(): LiveData<out Map<String, Any>> {
return data
}
}
В вашей деятельности:
private fun downloadInitInfo(){
val downloadTaskClass = DownloadTaskClass()
downloadTaskClass.execute("https://api.exchangeratesapi.io/latest?base=INR")
downloadTaskClass.returnMapMethod().observe(this, Observer {
println(it) // "it" contains the `mutableMap` data
})
}