Android: Accessing UI Element from timer thread

后端 未结 3 655
庸人自扰
庸人自扰 2020-12-01 14:05
public Button stb;
static int cnt=0;
public ArrayList Butgrp1 = new ArrayList();
Timer myt; 
TimerTask t;
stb.setOnClickListene         


        
相关标签:
3条回答
  • 2020-12-01 14:39

    You have to create the Handler in the UI Thread, i.e. in onCreate of your Activity.

    Because you create it in the run method of a background thread, the handler will execute your code in that very same background thread.

    You could also initialize your Handler directly:

    public class MyActivity extends Activity{
    
        private Handler handler = new Handler();
    
        //more code
    }
    

    And then don't use 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: Ok try this cleaned up code. Because you did not post your full Activity this won't work out of the box:

    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 讨论(0)
  • 2020-12-01 14:42

    You don't need to call runOnUIThread inside the handler. By calling post on the Handler instance, the runnable you pass will be executed on the UI thread at some point in the future. Change your code to look like this and it should work:

     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);
                    }
                });
    
    0 讨论(0)
  • 2020-12-01 14:49

    You can pass the Activity as a parameter to the method that runs the timertask, and then you can use Activity.runOnUiThread to execute your tasks in UI Thread. There are lots of post in stackoverflow site regarding the usage of runOnUiThread usage.

    0 讨论(0)
提交回复
热议问题