【问题标题】:Problem with returning a value when working with retrofit使用改造时返回值的问题
【发布时间】:2021-06-04 07:39:29
【问题描述】:

我有一个问题: 我有一个活动和一个班级。该类通过网络发出请求并返回结果。 Activity有这个类的一个对象,通过这个对象Activity访问这个类并返回信息。我附上有关该主题的代码:

class MainActivity : AppCompatActivity() {
    private lateinit var dataProcessing : DataProcessing
 override fun onCreate(savedInstanceState: Bundle?) {
 dataProcessing = DataProcessing()
private fun showData(){
// other code
dataList = dataProcessing.sendRequest(townName) // return null!
val wheather = dataList.get("nameTown")
     Log.d("Egor","two $wheather")
         val tem = dataList.get("temperature")
     Log.d("Egor","three $tem")
         dataShow(wheather, tem)
 
class DataProcessing {
    private val retrofitImpl: RetrofitImpl = RetrofitImpl()
    private  val mainActivity : MainActivity = MainActivity()
    lateinit var listString : MutableMap<String, String>
    var map: Map<String,String> = mapOf()
    internal fun getInfoToMainActivity(townName:String): Map<String, String>{
       sendRequest(townName)
        return listString
    }
    internal fun sendRequest(townName:String) : Map<String,String>{
 
        retrofitImpl.getRequest().showWeather(townName).enqueue(object : Callback<DateWeather> {
            var objectMainActivity = mainActivity ?: MainActivity()
            var listString= mutableMapOf<String, String>()
 
            override fun onResponse(call: retrofit2.Call<DateWeather>, response: Response<DateWeather>) {
                val dateWeather:DateWeather? = response.body()
                if (response.isSuccessful && dateWeather != null) {
                    val nameTown = dateWeather.weather.get(0).toString()
                    Log.d("Egor","nametown" + nameTown)
                    val size = nameTown.length - 1
                    listString.apply {
                        put("nameTown", nameTown.subSequence(13, size).toString())
                        put("temperature", dateWeather.main.temp!!.toInt().toString())
                        Log.d("Egor","one ${listString.get("nameTown")}")
                    }
                    map = listString.toMap()
                } else
                    Toast.makeText(MainActivity(), "Error", Toast.LENGTH_LONG).show()
            }
            override fun onFailure(call: Call<DateWeather>, t: Throwable) {
                Toast.makeText(MainActivity(), "network error", Toast.LENGTH_LONG).show()
            }
        })
        Log.d("Egor","step before returning the mep $map")
        return  listString;
    }
    }

按时间,日志显示如下:

2021-05-30 02:59:31.208 19871-19871/com.example.wheatherprog D/Egor:step before returning the map
2021-05-30 02:59:31.208 19871-19871/com.example.wheatherprog D/Egor: two null
2021-05-30 02:59:31.208 19871-19871/com.example.wheatherprog D/Egor: three null
2021-05-30 02:59:31.355 19871-19871/com.example.wheatherprog D/Egor: nametownWeather(main=Clear)
2021-05-30 02:59:31.355 19871-19871/com.example.wheatherprog D/Egor: one Clear

onResponse() 异步工作,因此在程序将 listString 传递给活动后,数据将写入 Map ( var listString)。结果,我没有数据,程序是空的。直接调用 onResponse() 是没有意义的,因为它不会返回任何东西。 我不想将数据处理中的代码移动到 activiti。但是如何从 Activity 向 DataProcessing 发出请求并从那里返回数据?

我真的希望得到帮助。

【问题讨论】:

  • 我对你的代码很困惑。你能把它们修好,把它放好吗?

标签: android kotlin retrofit


【解决方案1】:

您需要的是一个有助于充当某种回调的接口。你的逻辑假设是正确的,因为它是异步的,它会在一段时间后返回,直到那时数据已经回到你的活动中。

所以这是你可以做的。创建一个接口。

interface DataProcessingCallback {
        fun onSuccessfulDataProcessed(result: Map<String,String>)
    }

接下来我们在你的activity中实现这个接口,也就是接收回调的地方

class MainActivity : AppCompatActivity(), DataProcessingCallback {
        override fun onSuccessfulDataProcessed(result: Map<String, String>) {
            // Do stuff here
        }
    }

第三,我们将此接口传递给您的数据处理类,以便它可以调用它并在您的活动中获取回调

internal fun sendRequest(townName:String, dataProcessingCallback: DataProcessingCallback){
        // Stuff

        override fun onResponse(call: retrofit2.Call<DateWeather>, response: Response<DateWeather>) {
            val dateWeather:DateWeather? = response.body()
            if (response.isSuccessful && dateWeather != null) {
               // Stuff
                map = listString.toMap()
                dataProcessingCallback.onSuccessfulDataProcessed(map)   // Pass back to the callback
            } else
                Toast.makeText(MainActivity(), "Error", Toast.LENGTH_LONG).show()
        }
    }

【讨论】:

  • 谢谢!不幸的是,我现在不能尝试这个选项,但我有一个顾虑。我之前尝试过类似的东西,但是我遇到了在 onCreate() 中初始化变量的问题,即变量未初始化的返回异常的回调。如果我调用 onSuccessfulDataProcessed() 到 View 他们会落后于初始化吗?我是否正确理解我需要将 MainActivity 对象发送到 sendrequest()?
  • @Egor0702 我可能会误解你,但没有滞后,如果是滞后,唯一的滞后是你点击 api 并获得响应所花费的时间,这对于任何应用程序都是正常的。大多数应用程序通常会显示加载程序。是的,您需要对 sendRequest 对象的回调实现,如下所示dataList.get("nameTown", this) 这意味着活动,并且由于您已经在活动中实现了接口,这意味着您的活动是接收回调的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
  • 2010-09-10
  • 1970-01-01
相关资源
最近更新 更多