Android: доступ к элементу пользовательского интерфейса из потока таймера - PullRequest
20 голосов
/ 16 марта 2012
public Button stb;
static int cnt=0;
public ArrayList<RadioButton> Butgrp1 = new ArrayList<RadioButton>();
Timer myt; 
TimerTask t;
stb.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

myt.mschedule(new TimerTask() {

    @Override
    public void run() {

        // TODO Auto-generated method stub


        System.out.println("Entering run");
        Handler h=new Handler();

        h.post(new Runnable() {

            public void run() {

                // TODO Auto-generated method stub
                runOnUiThread(new Runnable() {

                    public void run() {
                        // TODO Auto-generated method stub
                        Butgrp1.get(cnt).setChecked(true);
                        cnt=cnt+1;
                        if(cnt>4)
                            cnt=0;
                        if(cnt>0)
                        //  Butgrp1.get(cnt-1).setChecked(false);
                        System.out.println(cnt);
                    }
                });


            }
        });

        //rg.getChildAt(cnt).setPressed(true);

    }
},1000,2000);

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

Ответы [ 3 ]

25 голосов
/ 16 марта 2012

Вы должны создать Handler в потоке пользовательского интерфейса, то есть в onCreate вашего Activity.

Поскольку вы создаете его в методе run фонового потока, обработчик выполнит ваш код в том же фоновом потоке.

Вы также можете инициализировать Handler напрямую:

public class MyActivity extends Activity{

    private Handler handler = new Handler();

    //more code
}

А потом не используйте runOnUIThread:

 handler.post(new Runnable() {
           public void run() {
                    // TODO Auto-generated method stub
                    Butgrp1.get(cnt).setChecked(true);
                    cnt=cnt+1;
                    if(cnt>4)
                        cnt=0;
                    if(cnt>0)
                    //  Butgrp1.get(cnt-1).setChecked(false);
                    System.out.println(cnt);
                }
            });

EDIT: Хорошо, попробуйте этот очищенный код. Поскольку вы не опубликовали свою полную активность, это не будет работать из коробки:

public class TestActivity extends Activity {

    private Button button;
    static int cnt=0;
    public ArrayList<RadioButton> buttonArray = new ArrayList<RadioButton>();
    private Timer timer = new Timer(); 

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                timer.schedule(new MyTimerTask(), 1000,2000);
            }
        });
    }


    private void doButtonStuff(){
        buttonArray.get(cnt).setChecked(true);
        cnt=cnt+1;
        if(cnt>4){
            cnt=0;
        }
        if(cnt>0){
            //  Butgrp1.get(cnt-1).setChecked(false);
            System.out.println(cnt);
        }
    }

    private class MyTimerTask extends TimerTask{

        @Override
        public void run() {        
            runOnUiThread(new Runnable() {              
                @Override
                public void run() {
                    doButtonStuff();
                }
            });
        }       
    }
}
0 голосов
/ 30 сентября 2014

Вы можете передать Activity как параметр методу, который запускает timertask, а затем вы можете использовать Activity.runOnUiThread для выполнения ваших задач в потоке пользовательского интерфейса.На сайте stackoverflow есть много постов, посвященных использованию runOnUiThread.

0 голосов
/ 16 марта 2012

Вам не нужно вызывать runOnUIThread внутри обработчика.При вызове post для экземпляра Handler передаваемый вами runnable будет выполняться в потоке пользовательского интерфейса в будущем.Измените свой код так, чтобы он выглядел следующим образом:

 Handler h=new Handler();

    h.post(new Runnable() {

        public void run() {

                    // TODO Auto-generated method stub
                    Butgrp1.get(cnt).setChecked(true);
                    cnt=cnt+1;
                    if(cnt>4)
                        cnt=0;
                    if(cnt>0)
                    //  Butgrp1.get(cnt-1).setChecked(false);
                    System.out.println(cnt);
                }
            });
...