Podstawy Androida: uruchamianie kodu w wątku UI

W punkcie uruchamiania kodu w wątku UI, czy jest jakaś różnica między:

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

Lub

MainActivity.this.myView.post(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

I

private class BackgroundTask extends AsyncTask<String, Void, Bitmap> {
    protected void onPostExecute(Bitmap result) {
        Log.d("UI thread", "I am the UI thread");
    }
}
Author: MC Emperor, 2012-10-12

7 answers

Żaden z nich nie jest dokładnie taki sam, chociaż wszystkie będą miały ten sam efekt netto.

Różnica między pierwszym a drugim jest taka, że jeśli zdarzy ci się być w głównym wątku aplikacji podczas wykonywania kodu, pierwszy (runOnUiThread()) natychmiast uruchomi Runnable. Drugi (post()) zawsze umieszcza Runnable na końcu kolejki zdarzeń, nawet jeśli jesteś już w głównym wątku aplikacji.

Trzeci, zakładając, że stworzysz i wykonasz instancja BackgroundTask, będzie tracić dużo czasu na wyciągnięcie wątku z puli wątków, aby wykonać domyślne no-op doInBackground(), zanim ostatecznie zrobi to, co wynosi post(). Jest to zdecydowanie najmniej efektywne z tych trzech. Użyj AsyncTask, jeśli rzeczywiście masz pracę do wykonania w wątku w tle, a nie tylko do użycia onPostExecute().

 251
Author: CommonsWare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-11 23:33:44

Podoba mi się ten z HPP comment , można go używać wszędzie bez żadnego parametru:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});
 202
Author: pomber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:31

Istnieje czwarty sposób użycia Handler

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});
 52
Author: vasart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 13:59:19

Odpowiedź Pombera jest do przyjęcia, jednak nie jestem wielkim fanem tworzenia nowych obiektów wielokrotnie. Najlepsze rozwiązania to zawsze te, które starają się złagodzić zapamiętywanie. Tak, istnieje automatyczne usuwanie śmieci, ale zachowanie pamięci w urządzeniu mobilnym mieści się w granicach najlepszych praktyk. Poniższy kod aktualizuje widok tekstu w usłudze.

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

}

Może być używany z dowolnego miejsca w taki sposób:

textViewUpdater.setText("Hello");
        textViewUpdaterHandler.post(textViewUpdater);
 17
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-18 13:52:18

Jeśli potrzebujesz użyć w fragmencie, powinieneś użyć

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

Zamiast

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

Ponieważ będzie wyjątek wskaźnika null w niektórych sytuacjach, takich jak fragment pagera

 3
Author: Beyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 14:32:10

Cześć chłopaki to jest podstawowe pytanie any away powiem

Use Handler

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});
 3
Author: raghu kambaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-01 04:50:25

Od Androida P możesz użyć getMainExecutor():

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

Z Android developer docs :

Zwraca wykonawcę, który będzie uruchamiał zadania w głównym wątku związanym z tym kontekstem. Jest to wątek używany do wysyłania wywołań do komponentów aplikacji (aktywności, usługi itp.).

Z CommonsBlog :

Możesz wywołać getMainExecutor () w kontekście, aby uzyskać Executor, który wykona swoje zadania w głównej aplikacji nić. Istnieją inne sposoby osiągnięcia tego celu, używając loopera i niestandardowej implementacji executora, ale jest to prostsze.

 1
Author: Dick Lucas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-09 03:54:48