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

Теперь, на основе вычислений в отдельном потоке, я вызываю функцию в основном классе потока пользовательского интерфейса, из которого был создан этот новый поток. В этой функции я обновляю пользовательский интерфейс. Мне сказали, что это не сработает, так как мне нужно вызвать основной поток пользовательского интерфейса.

Может ли кто-нибудь помочь мне с этим?

@Override
public void onListItemClicked(int index, Map<String, Object> data) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            // Issue command() on a separate thread
            wasCommandSuccess(command());
        }
    }).start();
}


private void wasCommandSuccess(boolean result){
    if (result == false){
        getUI(BasicUI.class).showAlert("Command failed!", "Unable to access");
    }
}
2
Sunny 10 Апр 2013 в 13:20
Обычно для этого используется AsyncTask. Я готов поспорить, что простой поиск в Интернете сказал бы вам об этом. См. stackoverflow.com/q/4369537/1856738
 – 
class stacker
10 Апр 2013 в 13:21
Мой класс уже расширяет другой класс
 – 
Sunny
10 Апр 2013 в 13:26
Да и что с того? Вам нужно было реализовать свой поток, поэтому вы сможете реализовать AsyncTask, не так ли?
 – 
class stacker
10 Апр 2013 в 13:28
Зачем ему переходить на AsyncTask, когда он уже использует Thread? Да, у вас есть более красивое имя AsyncTask, но на самом деле они делают то же самое. У каждого свои предпочтения, использование Thread не хуже, чем AnsyncTask.
 – 
Krypton
10 Апр 2013 в 13:35
Послушайте, если вы не хотите использовать AsyncTask, тогда вам придется использовать один из способов запуска Runnable, который имеет ссылку на результаты в потоке пользовательского интерфейса. Один метод использует Activity.runOnUIThread(), но он требует, чтобы у вас была ссылка на объект Activity.
 – 
class stacker
10 Апр 2013 в 13:39

1 ответ

Лучший ответ

Вы должны вызвать функцию wasCommandSuccess в runOnUiThread (); Итак, у вас должен быть такой код:

@Override
public void onListItemClicked(int index, Map<String, Object> data) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            // Issue command() on a separate thread
            final boolean result = command();
            // you need to pass your context (any of Activity/Service/Application) here before this
            context.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    wasCommandSuccess(result);
                }
            });
        }
    }).start();
}


private void wasCommandSuccess(boolean result){
    if (result == false){
        getUI(BasicUI.class).showAlert("Command failed!", "Unable to access");
    }
}
1
Krypton 10 Апр 2013 в 13:38
Этот фрагмент кода будет работать, только если он является частью Activity, реализующего Listener; это предположение, для которого в настоящее время нет никаких доказательств. Фрагмент кода, предоставленный @Sunny, может находиться где угодно.
 – 
class stacker
10 Апр 2013 в 13:35
Хе-хе, я это знал. Предположение Криптона было неверным.
 – 
class stacker
10 Апр 2013 в 13:36
И @Sunny and Krypton, откуда автоматически берется context?
 – 
class stacker
10 Апр 2013 в 14:01
LOL, это самый простой способ. Есть способ запускать что-то в потоке пользовательского интерфейса даже без какого-либо контекста.
 – 
Krypton
10 Апр 2013 в 14:06
У меня есть класс, который этим занимается. Поэтому я вызываю runOnUiThread (), используя этот класс
 – 
Sunny
10 Апр 2013 в 14:12