【问题标题】:CallBack after object instanciation, which contains asynchronous function对象实例化后的回调,包含异步函数
【发布时间】:2019-04-03 13:03:17
【问题描述】:

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

这里是代码

Product.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")
            }
        })
    }
}

GameActivity.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
}

【问题讨论】:

    标签: android api class asynchronous kotlin


    【解决方案1】:

    首先,我们假设您不想使用 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
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2017-01-15
      • 2019-01-27
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      相关资源
      最近更新 更多