简体   繁体   English

Android 定时器/定时器任务导致我的应用程序崩溃?

[英]Android timer/timertask causing my app to crash?

Just testing out a simple block of code in my mainActivity's onCreate:只需在我的 mainActivity 的 onCreate 中测试一个简单的代码块:

Timer timer2 = new Timer(); 
        TimerTask testing = new TimerTask() {
            public void run() { 
                Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();

            }
        };
        timer2.schedule(testing, 1000);

I get the "force close" error though.我得到了“强制关闭”错误。

What gives?是什么赋予了?

Alright for anyone else who runs into this, I fixed the problem by using a Handler and Runnable to do the Toast, which seems to be needed for UI interaction:好吧,对于遇到此问题的其他人,我通过使用 Handler 和 Runnable 来解决问题,这似乎是 UI 交互所必需的:

    final Handler handler = new Handler(); 
    Timer timer2 = new Timer(); 
    TimerTask testing = new TimerTask() {
        public void run() { 
            handler.post(new Runnable() {
                public void run() {
                    Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();
                }

            });


        }
    };
    timer2.schedule(testing, 1000);

I still don't understand why this is necessary though, perhaps someone could explain?我仍然不明白为什么这是必要的,也许有人可以解释一下? But hey at least this code works lol.但是,嘿,至少这段代码有效,哈哈。

Timer(Tasks) are bad: Do it the Android way.计时器(任务)不好:按照 Android 方式进行。 Use a Handler.使用处理程序。

As you can see in the code snippet, it's pretty easy to go that way too:正如您在代码片段中看到的那样,go 也很容易:

First we need a Handler that starts the Runnable after 100ms首先我们需要一个在 100ms 后启动 Runnable 的 Handler

private Handler handler = new Handler();
handler.postDelayed(runnable, 100);

And we also need the Runnable for the Handler我们还需要 Handler 的 Runnable

private Runnable runnable = new Runnable() {
   @Override
   public void run() {
      /* do what you need to do */
      foobar();
      /* and here comes the "trick" */
      handler.postDelayed(this, 100);
   }
};

So the “trick” is to tell the handler at the end to start the Runnable again.所以“诀窍”是在最后告诉处理程序再次启动 Runnable。 This way the runnable is started every 100ms, like a scheduleAtFixedRate() TimerTask, If you want it to stop, you can just call handler.removeCallback(runnable) and it won't start again, until you tell it to这样,runnable 每 100 毫秒启动一次,就像 scheduleAtFixedRate() TimerTask,如果你想让它停止,你可以调用handler.removeCallback(runnable)它不会再次启动,直到你告诉它

The app crashes because you are attempting to access elements of the UI thread (a toast) from a different thread (the timer thread).应用程序崩溃是因为您试图从不同的线程(计时器线程)访问 UI 线程(吐司)的元素。 You cannot do this!你不能做这个!

You can get round it by either:您可以通过以下任一方式绕过它:

Sending a handler message from the timer thread to the UI thread, and then showing the toast in the UI handler function.从计时器线程向 UI 线程发送处理程序消息,然后在 UI 处理程序 function 中显示 toast。

OR或者

In the timer code run use 'runOnUiThread':在计时器代码运行中使用“runOnUiThread”:

@Override

public void run() 

{

    mainActivity.runOnUiThread(new Runnable() {

        public void run() {

            // Access/update UI here

            Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();

        }

    });

}

@YoungMoney @YoungMoney

It works but only the first time... Did you make it display the Toast message every second??它有效,但只是第一次......你让它每秒显示 Toast 消息吗?

Mine only worked once...我的只工作过一次...

=== ===

Edit: Just realised your last line of code is missing the last value which is how often to repeat.编辑:刚刚意识到您的最后一行代码缺少最后一个值,即重复频率。

For anyone else concerned, change this:对于其他有关人员,请更改以下内容:

timer2.schedule(testing, 1000);

to this:对此:

timer2.schedule(testing, 1000, 2000);

If you want to start the timer in 1 second, and update every 2 seconds.如果你想在 1 秒内启动计时器,并且每 2 秒更新一次。

TimerTask task = new TimerTask() {
    @Override
    public void run() {
        //do something

    }
};

Timer t = new Timer();
t.schedule(task, 2000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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