Android - 是否有可能每毫秒至少运行一次线程更新?

时间:2013-10-08 15:08:07

标签: java android multithreading performance precision

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

我尝试运行一个线程并使用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 个答案:

答案 0 :(得分:2)

使用常规的java,硬件和Thread.sleep()之类的东西无法实现1ms的精度。

达到1ms精度所需的是实时平台。

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

  

Sun的杰出工程师Greg Bollella表示   Microsystems和实时Java的作者之一   规范,实时意味着“可靠和可靠的能力   可预测地推理和控制程序的时间行为   逻辑。“实时并不意味着”快速“,正如许多开发人员所说的那样   认为;它对现实世界的反应意味着可预测和可靠   事件是必需的。实时计算机将始终响应   你指定它的特定截止日期。取决于你的方式   设定最后期限,可以将多个系统称为实时。

见这个讨论: Java - alternative to thread.sleep

更具体地说,本文讨论了部署实时应用程序的可能性: http://www.embedded.com/electronics-blogs/cole-bin/4372870/Real-time-Android--real-possibility--really-really-hard-to-do---or-just-plain-impossible--

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

基本上,我认为你的股票市场应用程序运气不佳。如果这是针对您的公司的,您可以尝试生根每个设备并使用实时内核,但您正在冒险进入大多数未知的水域。没有保证即使使用这条路线也可以达到1ms的准确度。

...无论其


编辑:您的案例似乎不需要1ms的准确率。恰巧我的论文基于视听线索和同时感知。

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

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

答案 1 :(得分:1)

  

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

这不需要“每毫秒至少运行一次线程更新”。您可以找到MediaPlayer音乐的毫秒偏移量,并将其与预期值进行比较。您的期望值取决于您开始整个事情的时间和触摸事件的当前时间。

答案 2 :(得分:0)

class SampleTask extends TimerTask {
    public void run() {
       System.out.println("Hello World!"); 
    }
 }


 Timer timer = new Timer();
 timer.schedule(new SampleTask(), 1);

答案 3 :(得分:0)

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

首先,我认为1ms是努力实现的正确准确度。

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

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

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

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

修改

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

这也不太适用于耳机...