Android Activity.runOnUiThread не является статичным, так как я могу его использовать? - PullRequest
4 голосов
/ 24 сентября 2011

Например, если у меня есть поток, выполняющий дорогие вещи, и из этого потока я хочу запустить runOnUiThread в классе Main (Activity).Очевидно, я не должен делать экземпляр моего класса деятельности (Main).Так что, если я попытаюсь

 Main.runOnUiThread(mRunnable);

из моего потока, это выдаст мне сообщение об ошибке, говорящее, что это не статический метод, и поэтому к нему нельзя получить доступ моим способом.Теперь я понимаю, что класс активности доступен почти статически.
Как бы я это сделал?

(Кстати: я делаю это, потому что получаю CalledFromWrongThreadExceptionТолько оригинальный поток, создавший иерархию представлений, может касаться его представлений )

Ответы [ 6 ]

3 голосов
/ 24 сентября 2011

Ваш вопрос не дает достаточно подробностей, но, судя по всему, вы находитесь в частном внутреннем классе (Runnable?) В своей деятельности (Main). Если это так, вы можете написать:

Main.this.runOnUiThread(mRunnable);

или

runOnUiThread(mRunnable); //will see that there is no runOnUiThread in the current class and begin looking "upwards"

Также вы можете захотеть взглянуть на AsyncTask , в частности на обратные вызовы onPostExecute, onPreExecute и onProgressUpdate, которые выполняются в потоке пользовательского интерфейса.

3 голосов
/ 24 сентября 2011

Раунак имеет правильную идею. Я просто добавлю, что вы также можете указать целое число в методе sendEmptyMessage в качестве идентификатора обработчику. Это позволит вам создать один обработчик, который сможет обрабатывать все ваши обновления пользовательского интерфейса, например,

public static final int EXAMPLE = 0;
public static final int ANOTHER_EXAMPLE = 1;

private final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch( msg.what ){
            case EXAMPLE: 
                //Perform action
                break;
            case ANOTHER_EXAMPLE;
                //Perform action
                break;
        }
    }
} 

//Call to submit handler requesting the first action be called
handler.sendEmptyMessage(EXAMPLE);

Надеюсь, это поможет!

3 голосов
/ 24 сентября 2011

Вы должны использовать класс Handler .Класс обработчика выполняется в потоке пользовательского интерфейса.Когда вы закончите работу в своей ветке, позвоните handler.sendEmptyMessage(), откуда вы сможете вносить изменения в свой пользовательский интерфейс.

private final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
         // make changes to ui
    }
} 
2 голосов
/ 20 октября 2012

сначала создайте работоспособный снаружи onCreate. Как это:

private Runnable myRunnable = new Runnable() {
        @Override
        public void run() {

                        //work to be done

        }
    };

, а затем вызвать исполняемый файл, используя:

runOnUiThread(myRunnable);
0 голосов
/ 05 декабря 2015

все приведенные выше ответы не очень корректны.

1) если вы хотите, чтобы фрагмент кода выполнялся в потоке пользовательского интерфейса из любой базы кода потока.Вы можете сделать: Looper.getMainLooper (). post (new Runnable (...))

, потому что Looper.getMainLooper () является статической переменной и инициализируется в ActivityThread.

2), еслиВаш фрагмент исполняемого кода находится внутри действия, поэтому вы можете использовать:

MainActivity.this.runOnUiThread (...)

0 голосов
/ 05 июня 2015

Для тех, кто ищет простое мгновенное решение, следуйте простым шагам

  • Сделайте ссылку на ваш класс перед вашим onCreate() методом

    MyClass obj;
    
  • Инициализируйте это в вас onCreate() Метод

    obj = MyClass.this;
    
  • Звоните runOnUiThread()

    obj.runOnUiThread(new Runnable() {
        public void run() {
        //perform your UI tasks here
        }
    });
    

Надеюсьпомогает.

...