提问者:小点点

类不返回MutableMap对象


我用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())
    }
}

共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
    }
}

在你的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
    })
}