0

我正在使用 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())
    }
}
4

1 回答 1

2

您在方法中发出异步请求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
    })
}
于 2020-06-28T15:07:45.650 回答