Reputation: 299
I'm new to Android development and I would like to know what is the best practice to update the UI from another class.
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.
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?
Upvotes: 0
Views: 3704
Reputation:
Using 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
}
}
}
Upvotes: 0
Reputation: 2259
Here the documentation to AsyncTask.
It will help you to do some background tasks, and publish the result when finished to the main UI.
From the documentation:
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Example of code: from 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
}
}
Upvotes: 3