我用Kotlin制作了一个带有API的基本货币转换器应用程序。 为了下载信息,我创建了一个名为DownloadTaskClass的新类,它扩展了已弃用的AsyncTask类(我还没有学习java.util.concurrent包的其他类)。
DownloadTaskClass包含向MainActivity返回MutableMap的方法。 但是,我不能理解为什么这个方法不返回MutableMap对象。 这是类。
DownloadTaskClass.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())
}
}
您在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
}
}
在你的activity中:
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
})
}