Charles
Charles

Reputation: 299

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.

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

Answers (2)

user9782202
user9782202

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

Maurice
Maurice

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

Related Questions