Основы Android: запуск кода в потоке пользовательского интерфейса



С точки зрения выполнения кода в потоке пользовательского интерфейса, есть ли разница между:



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");
}
}
590   7  

7 ответов:

ни один из них не является точно таким же, хотя все они будут иметь одинаковый чистый эффект.

разница между первым и вторым заключается в том, что если вам случится быть on основной поток приложения при выполнении кода, первый (runOnUiThread()) будет выполнять Runnable немедленно. Второй (post()) всегда ставит Runnable в конце очереди событий, даже если вы уже в главном потоке приложения.

третий, предполагая, что вы создаете и выполняете экземпляр BackgroundTask, будет тратить много времени на захват потока из пула потоков, чтобы выполнить по умолчанию no-op doInBackground(), прежде чем в конечном итоге делает то, что составляет post(). Это, безусловно, наименее эффективно из трех. Используйте AsyncTask если у вас действительно есть работа в фоновом потоке, а не только за использование onPostExecute().

Мне нравится один из комментарий ГЭС, он может быть использован в любом месте без каких-либо параметров:

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 приемлем, однако я не большой поклонник создания новых объектов неоднократно. Лучшие решения всегда те, которые пытаются смягчить память свиньи. Да, есть автоматическая сборка мусора, но сохранение памяти в мобильном устройстве попадает в рамки лучшей практики. Приведенный ниже код обновляет текстовое представление в службе.

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);

Если вам нужно использовать в фрагменте вы должны использовать

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");
        }
    });

вместо

getActivity().runOnUiThread(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

потому что там будет исключение нулевого указателя в некоторой ситуации, как фрагмент пейджера

привет ребята это один основной вопрос любой прочь я говорю

использовать проводник

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

С Android P вы можете использовать getMainExecutor():

getMainExecutor().execute(new Runnable() {
  @Override public void run() {
    // Code will run on the main thread
  }
});

С Android developer docs:

возвращает исполнитель, который будет выполнять поставленные в очередь задачи в основном потоке, связанном с этим контекстом. Это поток, используемый для отправки вызовов компонентам приложения (действия, службы и т. д.).

С CommonsBlog:

вы можете вызвать getMainExecutor () в контексте, чтобы получить Исполнитель, который будет выполнять свои задания в главном потоке приложения. Есть и другие способы достижения этого, используя Looper и реализацию пользовательского исполнителя, но это проще.

Comments

    Ничего не найдено.