Android / Java-在onClick中使用计时器循环

时间:2018-08-17 09:32:31

标签: java android loops timer onclick

这是我的第一个问题,对于格式不正确,我深表歉意。 我正在使用Java并试图使计时器在单击按钮时在while循环内运行。一旦单击开始按钮,结果将导致.setText定期更改框中的文本。

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);
}`

问题在于,当按下开始按钮时,似乎什么也没发生。 另外,我也尝试重复计时器调用。尽管此方法有效,但它将只运行一次计时器调用,然后结束click函数。

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);
}

我无法为此找到任何东西或解决任何问题,因此非常感谢您的帮助。我确定我会遗漏一些明显的东西。谢谢。

2 个答案:

答案 0 :(得分:0)

您正在做的是您正在同时运行所有计时器,因此所有计时器都将在同一时间执行

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);
}`

答案 1 :(得分:0)

问题:

您的List<Child> childdren = new List<Child> { new Child { ParentName ="Parent1", ChildName ="Child1"}, new Child { ParentName ="Parent1", ChildName ="Child2"}, new Child { ParentName ="Parent1", ChildName ="Child3"}, new Child { ParentName ="Parent1", ChildName ="Child4"}, new Child { ParentName="Parent2", ChildName ="Child1"}, new Child { ParentName ="Parent2", ChildName ="Child2"}, new Child { ParentName ="Parent2", ChildName ="Child3"}, new Child { ParentName ="Parent2", ChildName ="Child4"}, new Child { ParentName ="Parent3", ChildName ="Child1"}, new Child { ParentName ="Parent3", ChildName ="Child2"}, }; var ChildByParentName = childdren.ToLookup(x => x.ParentName); foreach (var item in ChildByParentName) { Console.WriteLine(item.Key); // Print Parent Name foreach (var child in ChildByParentName[item.Key]) { Console.WriteLine("\t" + child.ChildName + ", "); // Print Child Names } } 方法:

Parent1
        Child1,
        Child2,
        Child3,
        Child4,
Parent2
        Child1,
        Child2,
        Child3,
        Child4,
Parent3
        Child1,
        Child2,

它的作用是创建一个新的处理程序,并发布(计划)一段要在5秒钟后运行的代码块,然后立即返回而无需实际执行该代码。

因此,当您多次调用此方法时,它将计划任务并立即返回并再次计划任务,依此类推。由于函数会立即返回,因此所有计划的Timer都将同时执行。

当您在无限循环中调用此方法时,它将永远调度并返回,并调度并返回等等,直到永远永远不会返回,从而导致应用程序冻结。


解决方案:

要解决您的方法,您可以修改public void Timer() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { item.setText(ruleOut(rulesList)); } }, 5000); } 方法以在计划任务执行后调用该方法。

Runnable

并将点击处理程序设置为:

run()

通过这种方式,一旦您单击按钮,将安排文本设置在5秒钟后完成,并且方法public void Timer() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { item.setText(ruleOut(rulesList)); Timer(); } }, 5000); } 将运行并再次安排任务。