简体   繁体   English

从Kotlin中的类更新UI的正确方法

[英]Proper way to update UI from a class in Kotlin

I'm new to Android development and I would like to know what is the best practice to update the UI from another class. 我是Android开发的新手,我想知道从另一个类更新UI的最佳实践是什么。

Example: When I enter an activity I start a function myClass.PerformCalculation() which takes some time, when the calculation is over I want to update the UI with the result of the calculation. 示例:当我进入活动时,我启动了一个函数myClass.PerformCalculation() ,该函数需要一些时间,当计算结束时,我想使用计算结果来更新UI。 This generates the following error: 这将产生以下错误:

CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

I was thinking about using a Broadcast Receiver in the activity and perform a SendBroadcast at the end of myClass.PerformCalculation() , is it a good practice? 我正在考虑在活动中使用广播接收器,并在myClass.PerformCalculation()的末尾执行SendBroadcast ,这是一个好习惯吗?

Here the documentation to AsyncTask . 这里是AsyncTask的文档。

It will help you to do some background tasks, and publish the result when finished to the main UI. 它将帮助您执行一些后台任务,并在完成后将结果发布到主UI。

From the documentation: 从文档中:

AsyncTask enables proper and easy use of the UI thread. 通过AsyncTask,可以正确,轻松地使用UI线程。 This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. 此类允许您执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。

Example of code: from Stack Answer 代码示例:来自Stack Answer

inner class someTask() : AsyncTask<Void, Void, String>() {
    override fun doInBackground(vararg params: Void?): String? {
        // ...
    }

    override fun onPreExecute() {
        super.onPreExecute()
        // ...
    }

    override fun onPostExecute(result: String?) {
        super.onPostExecute(result)
        // UPDATE UI HERE
    }
}

Using RxJava : 使用RxJava

object MyClass {
    fun performCalculation(): Single<Int> {
        return Single.fromCallable {
            //perform calculation
            1
        }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
    }
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MyClass.performCalculation().subscribe { result ->
            //update ui
        }
    }
}

Using Coroutines : 使用协程

object MyClass {
    fun performCalculation(): Deferred<Int> {
        return async(CommonPool) {
            //your calculation
            1
        }
    }
}

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        launch(UI) {
            val result = MyClass.performCalculation().await()
            //update ui
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM