如何在修改之前在 AsyncTask 中使用变量?

Posted

技术标签:

【中文标题】如何在修改之前在 AsyncTask 中使用变量?【英文标题】:How to use a variable in an AsyncTask before it is modified? 【发布时间】:2020-01-11 12:44:09 【问题描述】:

我想在 AsyncTask 中使用我的类的一个参数,但是这个参数在 AsyncTask 之后发生了变化。所以当 AsyncTask 执行时,这个变量已经改变了,我得到了参数的新值而不是旧的。

我尝试使用 AsyncTask.execute ,创建一个扩展 AsyncTask 的类,但无事可做。

data class Case(var id: Long, var nom: String, var nomCourt: String, var couleur: String, var couleurTexte: String, var prix: Double, var nombre: Int = 0)
class Moteur(): Parcelable 
    //I didn't past the code of the Parcelable, because it doesn't matter to this problem.
    var cases : List<Case> = listOf(
        Case(0, "Bouchon 1", "B1", "#008000", "#FFFFFF", 5.0),
        Case(1, "Bouchon 2", "B2", "#800000", "#000000", 1.5),
        Case(2, "Bouchon 3", "B3", "#000080", "#FFFFFF", 3.0),
        Case(3, "Bouchon 4", "B4", "#808000", "#000000", 7.0),
        Case(4, "Bouchon 5 qui est long et cher", "B5",  "#008080", "#FFFFFF", 15.0)
    )
    enregistrerCommande() 
        //Of course, the property nombre of the Cases have changed before this function is called, but here is not the problem. In the Log, I have the good values and next the wrong one.
        Log.i("REGCOM", "avant : $cases")
        AsyncTask.execute 
            val bdd = Room.databaseBuilder(context!!, MaBdd::class.java, "historique").build()
            val dao = bdd.historiqueDao()
            Log.i("REGCOM", "après : $cases[0]")
            for (i in cases) dao.insertAll(Historique(0L, i!!.nombre, false))
            idProchainAchat ++
            context!!.getSharedPreferences("all", Context.MODE_PRIVATE).edit().putLong("idProchainAchat", idProchainAchat).apply()
            bdd.close()
        
        cases.forEachit.nombre = 0
        prixCommande = 0.0
    

它应该在我的 db Historique 中注册属性 nombre 的值,但它总是注册五次 0。

感谢您的帮助!

PS 对不起,我的英语不好,我说法语。

【问题讨论】:

我无法按照您的操作进行操作,但如果您将所有数据类属性设为不可变,这似乎不太容易出错。 AsyncTask.execute 这是异步代码块,因此在执行之前会发生更改。将cases.forEachit.nombre = 0 移动到execute 代码块内 @AkakiKapanadze 好的,我想到了这一点,但是在这个函数之后,RecyclerView 会获取数据,所以我有旧数据而不是新数据。 【参考方案1】:

我刚刚找到了一个解决方案,也许不是最好的,但它确实有效。

fun enregistrerCommande() 
    val temp = mutableMapOf<Long, Int>()
    cases.forEach  temp[it.id] = it.nombre 

    doAsync 
        val bdd = Room.databaseBuilder(context!!, MaBdd::class.java, "historique").build()
        val dao = bdd.historiqueDao()
        for ((clef, valeur) in temp) dao.insertAll(Historique(0L, clef, valeur, false))
        idProchainAchat ++
        context!!.getSharedPreferences("all", Context.MODE_PRIVATE).edit().putLong("idProchainAchat", idProchainAchat).apply()
        bdd.close()
    
    cases.forEachit.nombre = 0
    prixCommande = 0.0


解决方案是将数据“保存”在地图中(我使用地图是因为我只需要两个值,但只要您使用此方法,列表就可以了,它不适用于指针(我认为当您编写val temp = cases 时,您会创建另一个列表,但在对象 Case 上使用相同的指针。我认为这是因为我的先例试验。))。我使用了anko的doAsync函数来减少代码量,但是AsyncTask.execute也可以。

我希望有人能够使用我的答案,尽管我的英语不好。

【讨论】:

不要为英语不好而道歉。你做得很好!

以上是关于如何在修改之前在 AsyncTask 中使用变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AsyncTask 更新全局变量

如何在小部件构建中使用之前使用异步方法修改变量?

在任何地方使用我的 AsyncTask 类中的变量

AsyncTask - 如何在AsyncTask中使用带有postDelayed(Runnable,int)的Handler?

如何在python中调用函数之前修改函数的本地变量

如何在 Android 中运行 AsyncTask?