0

我想编写一个需要在指定时间执行某些操作的 Android 应用程序(确切地说是游戏)。这些更新的精度应不低于 1ms。那可能吗?

我尝试运行一个线程并使用 System.nanoTime() 测量更新之间的时间。结果,有数百次更新之间的时间等于或长于 1 毫秒。

我能否以某种方式达到一种精度,以确保每 1ms 至少执行一个循环?

这是我用于测试的代码:

public class MyThread extends Thread
{
    private boolean running = false;
    public void setRunning(boolean running)
    {
        this.running = running;
    }

    public MyThread()
    {
        this.setPriority(MAX_PRIORITY);
    }

    @Override
    public void run()
    {
        long currentTimeNano = 0;
        long lastFrameTimeNano = 0;
        long nanoFrameDelay = 0;
        int longDelays = 0; //Number of delays >= 1ms

        while(running)
        {
            currentTimeNano = System.nanoTime();

            //Measure delay between updates in ns
            nanoFrameDelay = currentTimeNano - lastFrameTimeNano;

            if(nanoFrameDelay >= 1000000)
                longDelays++;

            lastFrameTimeNano = currentTimeNano;
        }
    }
}

先感谢您!

4

4 回答 4

2

使用常规的 java、硬件和类似 Thread.sleep() 的东西是不可能达到 1ms 的精度的。

达到 1 毫秒精度需要的是实时平台。

取自http://www.onjava.com/pub/a/onjava/2006/05/10/real-time-java-introduction.html

根据 Sun Microsystems 的杰出工程师、实时 Java 规范的作者之一 Greg Bollella 的说法,实时意味着“能够可靠且可预测地推理和控制程序逻辑的时间行为”。许多开发人员可能认为,实时并不意味着“快”;当需要对现实世界的事件做出反应时,这意味着可预测且可靠。实时计算机将始终在您为其分配的特定截止日期之前做出响应。根据您设置截止日期的方式,许多系统都可以称为实时系统。

请参阅此讨论: Java - thread.sleep 的替代品

更具体地说,本文讨论了如何部署实时应用程序: http ://www.embedded.com/electronics-blogs/cole-bin/4372870/Real-time-Android--real-possibility ——真的——真的——很难做到——或者——根本不可能——

或者这个:http ://www.ittc.ku.edu/~niehaus/classes/753-f10/notes/sarvesh_android.pdf

基本上,我认为您对股票市场应用程序不走运。如果这是为您的公司准备的,您可以尝试对每个设备进行生根并使用实时内核,但您正在冒险进入大多数未知领域。即使使用该路线,也无法保证 1 毫秒的精度。

然而....


编辑:您的案例似乎不需要 1ms 的精度。碰巧我的论文是基于视听线索和对同时性的感知。

长话短说,对于 2 个音频信号(1 个来自左耳,1 个来自右耳),只有当两个信号间隔超过 10 毫秒时,才能判断两个脉冲输入是否有延迟。大多数人在区分 50 毫秒时的事件顺序时遇到了问题。

对于视力,正常的眼睛只能在大约 150Hz 下工作,因此延迟小于 7ms 没有任何区别。我见过的最佳刷新率大约是 200Hz,或 5ms 延迟。但是,这仅用于检测明亮的闪光,而不是您确定 2 个事件并发的情况。对于类似于您正在尝试做的事情,我能够安全地获得长达 60 毫秒的延迟,而不会在视听同时性方面出现任何明显的不匹配。您的用例可能需要更少的东西。~50ms 似乎是一个神奇的数字。对于这种类型的准确性, sleep() 应该绰绰有余。您的案例不需要实时系统。

于 2013-10-08T15:17:03.360 回答
1

当用户要触摸屏幕(以毫秒为单位)时,我将有一个预先计算的时间列表,我想测量它与实际触摸时间之间的差异。

这不需要“每毫秒至少运行一次线程更新”。您可以从 中找出音乐的毫秒偏移量MediaPlayer,并将其与您的预期值进行比较。您的预期值基于您启动整个过程的时间和触摸事件的当前时间。

于 2013-10-08T15:39:02.890 回答
0
class SampleTask extends TimerTask {
    public void run() {
       System.out.println("Hello World!"); 
    }
 }


 Timer timer = new Timer();
 timer.schedule(new SampleTask(), 1);
于 2013-10-08T15:16:09.143 回答
0

您的问题是如何以足够准确的时间(1ms)将用户输入与音频输出相关联,以进行适当的工作。

首先,我认为 1ms 是努力达到的正确精度。

其次,这并不容易。JAVA 不是实时的,Android 也不是。我认为您不妨忘记所有传统方法,因为硬件、操作系统和语言的延迟变化太大。

第三,如果用户输入语音,您是否考虑过另一种格式?如果您的应用程序可以在播放音乐的同时进行录制,那么您将录制的(希望)是所有其他声音叠加在顶部的音乐。因此,您所要做的就是在录音和原件之间建立相关性,以衡量录音相对于原件的对齐情况,然后处理录音以获得可识别的用户声音。

这样就可以避免任何实时软件要求,并且您可以利用平台中唯一的半实时部分;声音输入和输出。信任平台实时播放和录制,用普通的方式做你的处理。

您不会在用户输入后立即生成用户反应时间测量结果,因此如果您需要在之后立即更新屏幕,则此技术可能不适合。但是,当您的测量完成时,它至少会是准确的。

编辑

用户的声音输入可能非常简单。例如,如果他们只是将手指放在麦克风上,那么录音会突然变得更安静。易于加工。或者,原始录音中不存在的录音音量的任何增加都可以被视为用户输入,而无需实际识别额外的声音是什么。

这也不太可能与耳机一起使用......

于 2013-10-09T04:20:56.660 回答