简体   繁体   中英

Android / java - Using a timer Loop inside an onClick

This is my first question so I apologise if the format isn't correct. I'm using java and trying to get a timer to run within a while loop when a button is clicked. The result should cause a .setText to alter the text in a box periodically once the start button is clicked.

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startBtn = findViewById(R.id.startButton);
    item = findViewById(R.id.Rule);

    startBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            while(true)
            {
                Timer();
            }
        }
    });
}
public void Timer()
{
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() 
        {
            @Override
            public void run()
            {
                item.setText()
            }
        }, 5000);
}`

The issue is that when the start button is hit, nothing seems to happen. Alternatively I also tried repeating the timer call instead. Whilst this worked it will only run the timer call once and then end the click function.

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startBtn = findViewById(R.id.startButton);
    item = findViewById(R.id.Rule);

    startBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Timer();
            Timer();
            Timer();
            Timer();
            Timer();
        }
    });
}

public void Timer()
{
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            item.setText(ruleOut(rulesList));
        }
    }, 5000);
}

I haven't been able to find anything or work anything out for this so any help is much appreciated. I'm sure that i'll be missing something obvious. Thank you.

what you are doing is you are running all the timers at the same time so all are getting executed at the same time try to run this code

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startBtn = findViewById(R.id.startButton);
    item = findViewById(R.id.Rule);

    startBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            for(int i = 5000; true; i= i+5000){
                Timer(i);
            }
        }
    });
}
public void Timer(int time)
{
    Handler handler = new Handler();
    handler.postDelayed(new Runnable()
    {
        @Override
        public void run()
        {
            item.setText(String.valueOf(time));
        }
    }, time);
}`

Problem:

Your Timer method:

public void Timer() {
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            item.setText(ruleOut(rulesList));
        }
    }, 5000);
}

What it does is create a new handler and posts(schedules) a block of code to run after 5 secs and returns immediately without actually executing that code.

So when you call this method multiple times, it schedules the task and returns immediately and schedules the task again and so on. Since the functions returns immediately, all the scheduled Runnable 's are executed at the same time.

When you call this method inside an infinite loop, it schedules and returns and schedules and return and so on forever and never returns, causing the freezing of app.


Solution:

To solve your method you can modify the run() method to call this method after the scheduled task has been executed.

public void Timer() {
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            item.setText(ruleOut(rulesList));
            Timer();
        }
    }, 5000);
}

And set your click handler as:

startBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Timer();
    }
});

In this way, as soon as you click the button, the setting of text will be scheduled to be done after 5 secs and the method Timer will run and schedule the task again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM