Реализация Handler-Looper в Android

  1. У меня есть активность с обработчиком (поток пользовательского интерфейса)
  2. Я запускаю новый поток и делаю handler.post(new MyRunnable()) - (новый рабочий поток)

В документации Android говорится о методе post: «Вызывает добавление Runnable r в очередь сообщений. Runnable будет запускаться в потоке, к которому прикреплен этот обработчик».

Обработчик прикреплен к потоку пользовательского интерфейса. Как Android может работать в том же потоке пользовательского интерфейса без создания нового потока?

Будет ли создан новый поток с использованием Runnable из handler.post()? Или из подкласса Runnable будет вызываться только метод run()?


person mobiledev Alex    schedule 15.03.2011    source источник


Ответы (2)


Обработчик прикреплен к потоку пользовательского интерфейса.

Правильный.

Как Android может работать в том же потоке пользовательского интерфейса без создания нового потока?

Любой поток, включая основной поток приложения («UI»), может вызывать post() для Handler (или для любого View, если уж на то пошло).

person CommonsWare    schedule 15.03.2011
comment
Будет ли создан новый поток с использованием Runnable из handler.post()? Таким образом, сообщение с runnable будет взято из очереди и будет запущен новый поток? Я не могу понять, что означает Runnable будет запускаться в потоке, к которому прикреплен этот обработчик. Как запустить runnable в том же потоке без создания нового потока? - person mobiledev Alex; 15.03.2011
comment
@androidev Алекс: Нет. Для каждого приложения существует только один основной поток приложения (UI). post() запустит ваш Runnable в этом потоке. - person CommonsWare; 15.03.2011
comment
@androidev Alex: Я так думаю, но, если быть до конца честным, я не совсем понимаю ваш вопрос. - person CommonsWare; 15.03.2011
comment
@CommonsWare: ОП пытается сказать, что когда вы создаете исполняемый файл, его метод запуска будет запускаться отдельным потоком. Тогда КАК вы можете запустить эту задачу в потоке пользовательского интерфейса. Потому что, когда вы вызываете runnable.start(), создается новый поток, верно? - person Ashwin; 02.09.2012
comment
@Ashwin: ОП пытается сказать, что когда вы создаете исполняемый файл, его метод запуска будет запускаться отдельным потоком. -- это неверно. Runnable может выполняться в отдельном потоке; он не запускается автоматически в отдельном потоке. Потому что, когда вы вызываете runnable.start(), создается новый поток, верно? -- нет. Это стандартная Java, как она вела себя последние 15 лет или около того. - person CommonsWare; 02.09.2012
comment
@CommonsWare: спасибо за ответ. Не могли бы вы указать мне на некоторую документацию, которая содержит полную информацию. Например, когда создается новый поток, а когда нет. - person Ashwin; 02.09.2012
comment
@Ashwin: Вообще говоря, новый поток создается, когда вы вызываете new Thread(). Некоторые вещи Android будут создавать потоки, особенно AsyncTask, но это задокументировано в самом классе (например, в AsyncTask), а не в каком-то центральном месте. - person CommonsWare; 02.09.2012

Вот грубый пример псевдодроида, как использовать обработчики — надеюсь, это поможет :)

class MyActivity extends Activity {

    private Handler mHandler = new Handler();

    private Runnable updateUI = new Runnable() {
        public void run() {
            //Do UI changes (or anything that requires UI thread) here
        }
    };

    Button doSomeWorkButton = findSomeView();

    public void onCreate() {
        doSomeWorkButton.addClickListener(new ClickListener() {
            //Someone just clicked the work button!
            //This is too much work for the UI thread, so we'll start a new thread.
            Thread doSomeWork = new Thread( new Runnable() {
                public void run() {
                    //Work goes here. Werk, werk.
                    //...
                    //...
                    //Job done! Time to update UI...but I'm not the UI thread! :(
                    //So, let's alert the UI thread:
                    mHandler.post(updateUI);
                    //UI thread will eventually call the run() method of the "updateUI" object.
                }
            });
            doSomeWork.start();
        });
    }
}
person Cephron    schedule 15.03.2011
comment
Таким образом, поток пользовательского интерфейса вызывает только метод run() объекта updateUI? И поток пользовательского интерфейса не будет создавать новый поток и вызывать start() для выполнения кода метода run() в новом потоке? - person mobiledev Alex; 16.03.2011
comment
Как я понимаю, это правильно. (Кажется, CommonsWare говорит то же самое выше, и он говорит с некоторым авторитетом. xD) - person Cephron; 16.03.2011
comment
@Cephron: ОП пытается сказать, что когда вы создаете исполняемый файл, его метод запуска будет запускаться отдельным потоком. Тогда КАК вы можете запустить эту задачу в потоке пользовательского интерфейса. Потому что, когда вы вызываете runnable.start(), создается новый поток, верно? - person Ashwin; 02.09.2012
comment
@Ashwin: Я так не думаю ... когда вы создаете новый объект Thread и вызываете thread.start(), создается новый поток. Обычно вы инициализируете новый объект Thread с помощью Runnable, но вы можете делать и другие вещи с Runnables, например отправлять их в обработчик. - person Cephron; 04.09.2012