0

I have to update a TextView from another class (not a activity) with the result from a method which can be slow to finish its search. While the method don't finish I thought set the TextView text to something like "loading..." and finally, after method result is ok, set the text to that result. Currently I'm doing something like this:

textView.setText("loading...");
Search s = searcher.search();
textView.setText(s.result);

Firstly, this still freezes the application until result is ok, once didn't not used new Threads. I know that to set content to Android widgets we have to do it inside the uiThread, but I don't know how to do it in my case, once I'm not inside a Activity.

In second place, that approach are not showing the "loading..." text. When I call that code the application just freezes and back with the final text.

Then, how to avoid that freeze/breaking until content is ok?

Lucas Sousa
  • 192
  • 3
  • 14

2 Answers2

1

Do not do heavy operation inside MainThread (UI) in Android. For your case take a look to AsyncTask. It give you a method doInBackground where you should make some background stuff (http request, file i/o) then you will get call onPostExecute, that method will called on UI Thread with the results of doInBackground method. Another example.

Dmytro Ivanov
  • 1,260
  • 1
  • 8
  • 10
  • Navigating through answers I noticed that is not good use AsyncTask to long operations, like operations that took 2 or more seconds to finish. In my case is not fixed but sometimes I can get long operations like that. How to proceed, then? – Lucas Sousa Dec 30 '18 at 15:20
  • For sure good approuch is ReactiveX. Read this article https://stackoverflow.com/questions/22933762/service-vs-thread-in-android – Dmytro Ivanov Dec 30 '18 at 15:29
  • Ohh services... Nice to know that it can be used. Anyway I tested my work using `AsycTask` ans it worked good! Thanks for pointing it out. :) – Lucas Sousa Dec 30 '18 at 16:48
0

I think the main thing to understand is that only UI specific tasks should run on the UI thread. If it is not UI related then it should run on another thread ideally as an AsyncTask.

Performing a search, generally speaking, is very performance heavy as you have pointed out. This will block the UI thread from updating the UI which will lead to unresponsive UIs and users may perceive this a crash or a slow app.

So firstly, to run the updating on the UI Thread.

runOnUiThread(() ->{textView.setText("loading...");});

then perform the search on a different thread

then once the search is finished update the UI using the same method as above

Richard Stokes
  • 385
  • 3
  • 11
  • Thank you for explanation about uiThread use. However, as I said, I'm not inside a activity to call `runOnUiThread()` directly like that, for example. If I find some way to call it in my custom class your approach is still valid to this situation? – Lucas Sousa Dec 30 '18 at 15:02
  • All UI changes in Android must run on the UI Thread. If it doesn't then Android will throw an exception. If your code is running without any exceptions that means it already is running on the UI Thread in which case you need to run the search on a different thread, ideally via an AsyncTask. The onPostExecute method called in an AsyncTask runs on the UI Thread and you can update the text again there. Please note that there is a difference between Threads and Classes. – Richard Stokes Dec 30 '18 at 15:07