对象实例化后的CallBack,其中包含异步函数

时间:2019-04-03 13:03:17

标签: android api class asynchronous kotlin

我有一个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
}

1 个答案:

答案 0 :(得分:2)

首先,我们假设您不想使用MVVM或类似的体系结构。但我确实建议您阅读有关Android体系结构组件(例如ViewModel和LiveData的资料),以了解应如何在android应用程序中完成数据流。

谈到基础知识(不是很干净),我们必须创建一个接口并将引用传递给Product类,一旦成功,您就必须使用该引用来调用活动以更新textview。

第1步:创建界面

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()实现内更新textview

class GameActivity : AppCompatActivity(),ProductListener {

     ...
     ...
     ...

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