Зачем использовать обработчики, когда runOnUiThread делает то же самое?

я наткнулся на обоих обработчики и runOnUiThread понятий. Но мне все еще кажется сомнительным, в каких именно фактах они расходятся.

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

например, рассмотрим Runnable Thread который выполняет веб-службу в фоновом режиме, и теперь я хочу обновить ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.

каков был бы лучший способ обновить мой пользовательский интерфейс? Должен ли я пойти на Handler или runOnUiThread?

Я все еще знаю, что мог бы использовать AsyncTask и onPostExecute. Но я просто хочу знать разницу.

5 ответов


активности.runOnUiThread() является частным случаем более общего обработчики. С Handler вы можете создать свой собственный запрос события в своем собственном потоке. Используя Handlers инстанцируется с конструктор по умолчанию не значит "код будет работать в потоке UI" в целом. По умолчанию обработчики привязаны к Thread из которого они были созданы.

создать Handler это гарантировано для привязки к UI (main) thread вы должны создать


обработчик имеет много работы, как сообщение передает и частое обновление пользовательского интерфейса, если вы запускаете поток для любого запуска задачи .Обработчик позволяет отправлять и обрабатывать сообщения и запускаемые объекты, связанные с MessageQueue потока, что очень полезно во многих приложениях, таких как bluetooth-чат, wifi-чат ... и обработчик имеет как метод PostDelay и PostAtTime, с помощью которого вы можете играть вокруг любого представления для анимации и изменения видимости и так далее

вы должны посмотреть в это

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/tools/testing/activity_testing.html


после ответа HitOdessit.

вы можете создать такой класс.

public class Global{
    private static Handler mHandler = new Handler(Looper.getMainLooper());
    public static void runOnUiThread(Runnable action){
        mHandler.post(action);
    }
}

а затем назовите это так.

Global.runOnUiThread(new Runnable(){
    //Your code
});

и это можно запустить из любого места (где у вас есть доступ к вашему глобальному классу).


обработчики были старым способом (уровень API 1) делать вещи, а затем AsycTask (уровень API 3) были введены, наряду с более сильным акцентом на использовании runOnUIThread (уровень API 1). Вы должны избегать использования обработчиков как можно больше, и предпочитают два других в зависимости от ваших потребностей.


каков был бы лучший способ обновить мой пользовательский интерфейс? Должен ли я пойти на Handler или runOnUiThread?

если Runnable нужно обновить пользовательский интерфейс, разместить его на runOnUiThread.

но не всегда можно опубликовать Runnable в потоке пользовательского интерфейса.

подумайте о сценарии, где вам нужно выполнить работа сети / ввода-вывода или вызов веб-службы. В этом случае, вы не можете писать Runnable в поток пользовательского интерфейса. Он бросит android.os.NetworkOnMainThreadException

этот тип Runnable должен работать в другом потоке, например HandlerThread. После завершения работы, вы можете отправить результат обратно в поток пользовательского интерфейса с помощью Handler, который был связан с UI-потоке.

public void onClick(View view) {

    // onClick on some UI control, perform Network or IO operation

    /* Create HandlerThread to run Network or IO operations */
    HandlerThread handlerThread = new HandlerThread("NetworkOperation");
    handlerThread.start();

    /* Create a Handler for HandlerThread to post Runnable object */
    Handler requestHandler = new Handler(handlerThread.getLooper());

   /* Create one Handler on UI Thread to process message posted by different thread */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
    requestHandler.post(r1);
    requestHandler.post(r2);

}

class NetworkRunnable implements Runnable{
    String url;
    Handler uiHandler;

    public NetworkRunnable(String url,Handler uiHandler){
        this.url = url;
        this.uiHandler=uiHandler;
    }
    public void run(){
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL(url);
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ((line = buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Runnable", "After IO call:"+ text.toString());

            Message msg = new Message();

            msg.obj = text.toString();

            /* Send result back to UI Thread Handler */
            uiHandler.sendMessage(msg);


        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}