【问题标题】:Class Doesn't Return A MutableMap Object类不返回 MutableMap 对象
【发布时间】:2020-10-18 18:50:02
【问题描述】:

我使用 Kotlin 制作了一个带有 API 的基本货币转换器应用程序。为了下载信息,我创建了一个名为 DownloadTaskClass 的新类,它扩展了已弃用的 AsyncTask 类(我还没有学习 java.util.concurrent 包的其他类)。

DownloadTaskClass 包含一个将 MutableMap 返回到 MainActivity 的方法。但是,我不明白为什么这个方法没有返回 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())
    }
}

【问题讨论】:

    标签: android kotlin android-asynctask mutablemap


    【解决方案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
        })
    }
    

    【讨论】:

    • 实际上,我从 DownloadTaskClass 返回的这个 mutableMap 对象将在应用程序启动后立即在我的 MainActivity 中使用。而且我不希望它在返回之前花费很多时间。如果没有 LiveData,有什么方法可以实现这一点吗?我还没学呢。
    • 你可以使用一些监听器。或者您可以参考此答案stackoverflow.com/a/62542551/1731626 来创建AsyncTask 的替代方案。祝你好运!
    • 知道了。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2016-05-14
    • 2023-04-01
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多