Правильный способ обновления пользовательского интерфейса из класса в Котлине - PullRequest
0 голосов
/ 19 сентября 2018

Я новичок в разработке для Android, и я хотел бы знать, как лучше обновлять пользовательский интерфейс из другого класса.

Пример: когда я вхожу в действие, я запускаю функцию myClass.PerformCalculation(), которая занимает некоторое время, когда вычисление закончено, я хочу обновить пользовательский интерфейс с результатом вычисления.Это приводит к следующей ошибке:

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

Я думал об использовании Broadcast Receiver в упражнении и выполнении SendBroadcast в конце myClass.PerformCalculation(), это хорошая практика?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Использование 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
        }
    }
}

Использование Сопрограммы :

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
        }
    }
}
0 голосов
/ 19 сентября 2018

Вот документация к AsyncTask .

Это поможет вам выполнить некоторые фоновые задачи и опубликовать результат по завершении в основном интерфейсе пользователя.

Из документации:

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса.Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

Пример кода: из 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...