如何降低视频下载()延迟Android中视频下载、Android

2023-09-09 21:04:23 作者:囚歌.

我产生定时事件在一个(非UI)的循环线程在Android应用程序,我需要这些事件发生在precise间隔时间,(precise在这里是指不改变任何超过+/- 5的毫秒)。 +/- 10的毫秒(当然+/- 20的毫秒)的任何​​错误可被用户感知。在这个循环的顶部余做取可变的时间量的一些其他的计算,但在循环的底部,我需要的事件发生在一个$ P $对计算时间

I am generating timing events in a loop in a (non-UI) thread in an Android application, and I need those events to occur at precise intervals in time, (precise here means not varying any more than +/- 5 millisecs). Any errors of +/-10 millisecs (and certainly +/- 20 millisecs) can be perceived by the user. At the top of this loop I do some other calculations that take a variable amount of time, but at the bottom of the loop, I need the event to occur at a pre-calculated time.

一个higly简化版本(没有异常处理)的一个尝试,我非UI线程如下:

A higly simplified version (without exception handling) of one attempt at my non-UI thread is below:

public final void run() {

    long loopTime = 2500L;
    long eventTime = (System.nanoTime() / 100000L) + loopTime;

    while (true) {

        calcutionsTakingVaryingAmountOfTime(); // takes 200 millisecs or less

        long eventWait = eventTime - (System.nanoTime() / 100000L);
        Thread.sleep(eventWait / 10L);
        listener.onEvent();

        eventTime = eventTime + loopTime;
    }
}

这是调用 listener.onEvent(),需要加以precisely时机。

It is the call to listener.onEvent() that needs to be precisely timed.

在上面的例子中,时间变量 LOOPTIME eventTime eventWait 测量时间在毫秒的十分之一。这位前pressions (System.nanoTime()/ 100000L)测量电流的时间也同样在一毫秒的十分之一。

In the example above, the timing variables loopTime, eventTime, and eventWait measure time in tenths of a millisec. The expressions (System.nanoTime() / 100000L) measuring current time are likewise in tenths of a millisec.

我绝对肯定, calcutionsTakingVaryingAmountOfTime()的总是的花费不到200的毫秒,并调用监听器。的onEvent()只是少数的毫秒。因此,作为它的立场,与 LOOPTIME 设置为 2500L ,我的事件应该发生的每一个250的毫秒。

I am absolutely certain that calcutionsTakingVaryingAmountOfTime() always takes less than 200 millisecs, and the call to listener.onEvent() is just a few millisecs. So as it stands, with loopTime set to 2500L, my events ought to occur every 250 millisecs.

我已经intstrumented我的code(未显示)打印到 Log.d()视频下载的等待时间( )唤醒时间。也就是说,我计算

I have intstrumented my code (not shown) to print to Log.d() the latency in the Thread.sleep() wake up time. That is, I calculate

long latency = (System.nanoTime() / 100000L) - eventTime

返回视频下载(),并打印到 Log.d后立即()

当我运行这在模拟器中,我找到的是,延迟通常跳1至50的毫秒(除以10,得到的结果进入的毫秒后)在相继通过循环通过,偶尔值高达一个半秒钟。当一个实际的设备上运行,事情都相当好一点,但还是有一点摇晃(甚至还在,模拟器的行为使我怀疑这会发生在用户的设备)。

When I run this in the emulator, what I find is that latency (after dividing by 10 to get the result into millisecs) is normally jumping between 1 and 50 millisecs in successive passes through the loop, with occasional values as high as a half a second. When run on an actual device, things are quite a bit better, but still a little wobbly (and even still, the emulator behavior makes me wonder if this is going to happen on users' devices).

要设法稳住我的事件和控制延迟,我尝试过其他几种方法:

To try to steady my event and control the latency, I tried several other approaches:

在更换了视频下载(eventWait / 10L)调用,通过调用 this.wait(eventWait / 10L) (完全不恰当地使用wait()的,我所知道的)

In replaced the Thread.sleep(eventWait / 10L) call, with a call to this.wait(eventWait / 10L) (a completely inappropriate use of wait(), I know)

我操纵进入循环,调用之前线程优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO)就像是在Android的库所做的一切。

I manipulated the thread priorities prior to entering the loop, calling Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO) like is done all over the android libraries

但没有改善在所有在这些等待时间。

But there was no improvement at all in the latency with these.

的一种方法是steadys事件,并缩短了延迟的小于2或3的毫秒的,很少打嗝是替换视频下载()通过轮询循环调用:

The one approach that steadys the event, and reduces the latency to less than 2 or 3 millisecs, and rarely hiccups is to replace the Thread.sleep() call by a polling loop:

while ((System.nanoTime() / 100000L) < eventTime)
    ;

在一方面,我觉得自己像在自由喝醉的水手尴尬的消费机器周期。在另一方面,我开始觉得没有更好的办法,我就烧了机器周期的轮询循环,减少我的延迟,并符合我的标准。当然,在我的应用程序去的背景下,我停下我的线,所以这个查询循环工作。但是,什么是浪费。

On the one hand, I feel embarrassed spending machine cycles like a drunken sailor on liberty. On the other hand, I am beginning to think there is no better way, and I should burn the machine cycles in the polling loop to reduce my latency, and meet my specification. Of course, when my app goes to the background, I pause my thread, so this polling loop works. But what a waste.

任何想法将大大AP preciated。

Any ideas would be greatly appreciated.

推荐答案

我使用的是与处理程序类似用途延迟的消息。它可以是有点矫枉过正。在你的情况我会看看到定时器类。

I'm using delayed messages with Handler for similar purpose. It can be little overkill. In you case I would take a look to Timer class.

mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        Log.v("TEST", " tick");
    }
}, 0, 250);

这给了我的等待时间+ -2时的毫秒模拟器。

This gives me latency +-2 millisecs at emulator.