【问题标题】:Making a interval timer in Java android在Java android中制作间隔计时器
【发布时间】:2012-10-17 12:03:27
【问题描述】:

我计划使用计时器创建一个间隔应用程序。它应该只是最基本的,所以当我了解了基础知识后,我将不得不添加更多内容。我想要实现的是选择一个间隔应该持续的分钟数,但是这个间隔应该持续多少次。就像一个持续 1 分钟并持续 8 次的间隔。 问题是最好使用哪个计时器?我已经在 Android 倒数计时器上试过了,它似乎可以工作。但是还有其他更好的吗?

【问题讨论】:

    标签: java android timer intervals


    【解决方案1】:

    我总是建议使用Handler

    它比内置类多一点工作,但我发现它的效率要高得多,而且你可以更好地控制它。

    Handler 是一个类,它将在特定的Looper / Thread 上处理代码执行,默认情况下,它是在其中创建的线程,否则您可以通过传入 Looper 来指定 Handler 执行其代码的位置到 Handler 构造函数,例如 - new Handler(Looper.getMainLooper());

    我推荐 looper 的原因是因为你有更高的控制灵活性,因为它是一个比 TimerTask 方法略低的抽象。

    通常它们对于跨线程执行代码非常有用。例如。对于跨线程传输数据很有用。

    两个主要用途是:

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    
        final Handler h = new Handler();
        h.postDelayed(new Runnable()
        {
            private long time = 0;
    
            @Override
            public void run()
            {
                // do stuff then
                // can call h again after work!
                time += 1000;
                Log.d("TimerExample", "Going for... " + time);
                h.postDelayed(this, 1000);
            }
        }, 1000); // 1 second delay (takes millis)
    }
    

    简单易用!

    或者您可以使用消息来减少对象的创建。如果您正在考虑高速更新 UI 等 - 这将减少垃圾收集器的压力。

    class MainActivity extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
    
            MyTimers timer = new MyTimers();
            timer.sendEmptyMessage(MyTimers.TIMER_1);
            timer.sendEmptyMessage(MyTimers.TIMER_2);
    
        }
    
    
        public static class MyTimers extends Handler
        {
    
            public static final int TIMER_1 = 0;
            public static final int TIMER_2 = 1;
    
            @Override
            public void handleMessage(Message msg)
            {
                switch (msg.what)
                {
                    case TIMER_1:
                        // Do something etc.
                        Log.d("TimerExample", "Timer 1");
                        sendEmptyMessageDelayed(TIMER_1, 1000);
                        break;
                    case TIMER_2:
                        // Do another time update etc..
                        Log.d("TimerExample", "Timer 2");
                        sendEmptyMessageDelayed(TIMER_2, 1000);
                        break;
                    default:
                        removeMessages(TIMER_1);
                        removeMessages(TIMER_2);
                        break;
                }
            }
        }
    }
    

    显然,这不是完整的实现,但它应该可以让您领先一步。

    【讨论】:

    • 我只想指出一个重要的注意事项,关于这种通过递归调用实现间隔的方法。如果您正在做的事情需要一定的时间,则间隔频率将始终大于实时频率。例如,您在一秒钟后调用该方法,然后执行一些操作(可能需要 50 毫秒),然后在 1 秒后调用该方法。实际频率不是 1 秒,而是 1050 毫秒,甚至更令人困惑的可能是随机的,具体取决于应用程序执行您真正想做的事情所花费的时间。
    • 编辑:如果实时频率对你来说真的很重要,我宁愿推荐使用 Timer 类和 scheduleAtFixedRate 方法。
    • @RaphaelC - 频率实际上会降低,因为每个间隔都更长,因此该方法的调用频率较低。周期增加,但频率降低。所以1000ms是周期,因此1/sec是频率,所以如果周期是1050ms,那么频率大约是0.95/sec
    • @RaphaelC,看起来Timer class 也不是“实时的”,但可以通过一些垃圾处理和其他耗时任务的处理来接近预期的间隔。 > 此类不提供实时保证:它使用 Object.wait(long) 方法安排任务。
    • @topher217 尽管如此,正如您所说,它提供了比上面讨论的递归解决方案更接近实时的行为。此外,“实时”是一个非常广泛的概念,许多人很难达成一致,尤其是在涉及相对论时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多