首页 > 解决方案 > 对象实例化后的回调,包含异步函数

问题描述

我有一个 Product 类,它是用代码构造的。此代码用于调用开放食品事实 API 以实例化所有类变量。事实上,API 调用是一个异步函数。所以在我的主线程中,当我尝试访问我的对象参数时,它是空的。由于我无法中断主线程,我想如何对我的对象实例化进行回调?

这是代码

产品.kt

class Product(code: Long) {

    val client = OkHttpClient()

    var name: String? = null
    var imageUrl: String? = null
    var packerCode: Int? = null
    var packerCity: String? = null
    var lat: Int? = null
    var long: Int? = null

    init {
        run("https://fr.openfoodfacts.org/api/v0/produit/$code.json")
    }

    private fun run(url: String) {
        val request = Request.Builder()
            .url(url)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call?, e: IOException) {}
            override fun onResponse(call: Call?, response: Response){
                val jsonData = response.body()?.string()
                val Jobject = JSONObject(jsonData)

                name = Jobject.getJSONObject("product").getString("product_name")
            }
        })
    }
}

游戏活动.kt

class GameActivity : AppCompatActivity(){
   override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_game)

   val textView: TextView = findViewById(R.id.productName) as TextView
   val product = Product(3564700014677)
   // Product.name empty
   textView.text = product.name
}

标签: androidapiclassasynchronouskotlin

解决方案


首先,我们假设您不想使用 MVVM 左右的架构。但我真的建议您阅读有关 ViewModel、LiveData 等 Android 架构组件的信息,以了解应如何在 Android 应用程序中完成数据流。

回到基础(不是很干净的方式),我们必须创建一个接口并将引用传递给 Product 类,成功后您可以使用引用调用活动来更新文本视图。

第一步:创建接口

interface ProductListener
{
    fun onSuccess()
}

第 2 步:在您的活动中实现 ProductListener

class GameActivity : AppCompatActivity(),ProductListener {

 ...
 ...
 ...

 override fun onSuccess() {

    }
}

第 3 步:将侦听器/活动引用传递给 Product 类

val product = Product(3564700014677, this) //inside your activity

class Product(code: Long, var listener: ProductListener) {

...
...
private fun run(url: String) {
        val request = Request.Builder()
            .url(url)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call?, e: IOException) {}
            override fun onResponse(call: Call?, response: Response){
                val jsonData = response.body()?.string()
                val Jobject = JSONObject(jsonData)

                name = Jobject.getJSONObject("product").getString("product_name")

                // invoke listener here to let activity know the response

                 listener.onSuccess()
            }
        })
    }

}

第 4 步:更新活动的 onSuccess() 实现中的文本视图

class GameActivity : AppCompatActivity(),ProductListener {

     ...
     ...
     ...

     override fun onSuccess() {
            textView.text = product.name
        }
    }

推荐阅读