С точки зрения запуска кода в потоке пользовательского интерфейса существует ли разница между:
MainActivity.this.runOnUiThread(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } });
или
MainActivity.this.myView.post(new Runnable() { public void run() { Log.d("UI thread", "I am the UI thread"); } });
а также
private class BackgroundTask extends AsyncTask<String, Void, Bitmap> { protected void onPostExecute(Bitmap result) { Log.d("UI thread", "I am the UI thread"); } }
Ни один из них не является точно таким же, хотя все они будут иметь одинаковый чистый эффект.
Разница между первой и второй заключается в том, что если вы выполняете основной поток приложений при выполнении кода, первый ( runOnUiThread()
) немедленно выполнит Runnable
. Второй ( post()
) всегда помещает Runnable
в конец очереди событий, даже если вы уже находитесь в главном потоке приложения.
Третий, предполагая, что вы создаете и выполняете экземпляр BackgroundTask
, будет тратить много времени на захват потока из пула потоков, чтобы выполнить по умолчанию no-op doInBackground()
, прежде чем в конечном итоге делать то, что составляет post()
, Это, безусловно, наименее эффективный из трех. Используйте AsyncTask
если у вас есть работа, выполняемая в фоновом потоке, а не только для использования onPostExecute()
.
Мне нравится комментарий от HPP , его можно использовать везде без каких-либо параметров:
new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Log.d("UI thread", "I am the UI thread"); } });
Существует четвертый способ использования Handler
new Handler().post(new Runnable() { @Override public void run() { // Code here will run in UI thread } });
Ответ Pomber приемлем, но я не большой поклонник создания новых объектов. Лучшими решениями всегда являются те, которые пытаются уменьшить шум памяти. Да, есть сбор мусора, но сохранение памяти в мобильном устройстве подпадает под оптимальную практику. Код ниже обновляет TextView в службе.
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; } }
Его можно использовать из любого места:
textViewUpdater.setText("Hello"); textViewUpdaterHandler.post(textViewUpdater);