In the viewpoint of running code in the UI thread, is there any difference between:
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
I like the one from HPP comment, it can be used anywhere without any parameter:
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
None of those are precisely the same, though they will all have the same net effect.
The difference between the first and the second is that if you happen to be on the main application thread when executing the code, the first one (runOnUiThread()
) will execute the Runnable
immediately. The second one (post()
) always puts the Runnable
at the end of the event queue, even if you are already on the main application thread.
The third one, assuming you create and execute an instance of BackgroundTask
, will waste a lot of time grabbing a thread out of the thread pool, to execute a default no-op doInBackground()
, before eventually doing what amounts to a post()
. This is by far the least efficient of the three. Use AsyncTask
if you actually have work to do in a background thread, not just for the use of onPostExecute()
.
If you need to use in Fragment you should use
private Context context;
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
}
((MainActivity)context).runOnUiThread(new Runnable() {
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
instead of
getActivity().runOnUiThread(new Runnable() {
public void run() {
Log.d("UI thread", "I am the UI thread");
}
});
Because There will be null pointer exception in some situation like pager fragment
use Handler
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
// Code here will run in UI thread
}
});
The answer by Pomber is acceptable, however I'm not a big fan of creating new objects repeatedly. The best solutions are always the ones that try to mitigate memory hog. Yes, there is auto garbage collection but memory conservation in a mobile device falls within the confines of best practice. The code below updates a TextView in a service.
TextViewUpdater textViewUpdater = new TextViewUpdater();
Handler textViewUpdaterHandler = new Handler(Looper.getMainLooper());
private class TextViewUpdater implements Runnable{
private String txt;
@Override
public void run() {
searchResultTextView.setText(txt);
}
public void setText(String txt){
this.txt = txt;
}
}
It can be used from anywhere like this:
textViewUpdater.setText("Hello");
textViewUpdaterHandler.post(textViewUpdater);
As of Android P you can use getMainExecutor()
:
getMainExecutor().execute(new Runnable() {
@Override public void run() {
// Code will run on the main thread
}
});
From the Android developer docs:
Return an Executor that will run enqueued tasks on the main thread associated with this context. This is the thread used to dispatch calls to application components (activities, services, etc).
From the CommonsBlog:
You can call getMainExecutor() on Context to get an Executor that will execute its jobs on the main application thread. There are other ways of accomplishing this, using Looper and a custom Executor implementation, but this is simpler.