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

时间:2018-09-19 11:36:01

标签: android kotlin

我是Android开发的新手,我想知道从另一个类更新UI的最佳实践是什么。

示例:当我进入活动时,我启动了一个功能myClass.PerformCalculation(),该功能需要一些时间,计算结束后,我想使用计算结果来更新UI。 这将产生以下错误:

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

我正在考虑在活动中使用广播接收器,并在SendBroadcast的末尾执行myClass.PerformCalculation(),这是一个好习惯吗?

2 个答案:

答案 0 :(得分:3)

此处是AsyncTask的文档。

它将帮助您执行一些后台任务,并在完成后将结果发布到主UI。

从文档中:

  

AsyncTask允许正确且轻松地使用UI线程。这个班   允许您执行后台操作并在   UI线程,而无需操纵线程和/或处理程序。

代码示例:,来自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
    }
}

答案 1 :(得分:0)

使用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
        }
    }
}

使用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
        }
    }
}