I\'ve built a simple music player in Android. The view for each song contains a SeekBar, implemented like this:
public class Song extends Activity implement
I use Handler
with Looper.getMainLooper()
. It worked fine for me.
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
// Any UI task, example
textView.setText("your text");
}
};
handler.sendEmptyMessage(1);
If you do not want to use runOnUiThread
API, you can in fact implement AsynTask
for the operations that takes some seconds to complete. But in that case, also after processing your work in doinBackground()
, you need to return the finished view in onPostExecute()
. The Android implementation allows only main UI thread to interact with views.
In my case,
I have EditText
in Adaptor, and it's already in the UI thread. However, when this Activity loads, it's crashes with this error.
My solution is I need to remove <requestFocus />
out from EditText in XML.
Kotlin coroutines can make your code more concise and readable like this:
MainScope().launch {
withContext(Dispatchers.Default) {
//TODO("Background processing...")
}
TODO("Update UI here!")
}
Or vice versa:
GlobalScope.launch {
//TODO("Background processing...")
withContext(Dispatchers.Main) {
// TODO("Update UI here!")
}
TODO("Continue background processing...")
}
My solution to this:
private void setText(final TextView text,final String value){
runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText(value);
}
});
}
Call this method on a background thread.
Usually, any action involving the user interface must be done in the main or UI thread, that is the one in which onCreate()
and event handling are executed. One way to be sure of that is using runOnUiThread(), another is using Handlers.
ProgressBar.setProgress()
has a mechanism for which it will always execute on the main thread, so that's why it worked.
See Painless Threading.