android - 为什么当手指触摸屏幕时 Android 上的计时器更准确?

标签 android performance delphi firemonkey android-timer

在 Delphi 10.1 Berlin 中,我正在制作一个 Android 应用程序。我创建了一个这样的计时器:

fTimer := TTimer.Create(nil);
fTimer.Interval := 1;
fTimer.OnTimer := OnTimer;
fTimer.Enabled := True;

OnTimer 事件中,我只是这样做:

procedure TMyForm.OnTimer(Sender: TObject);
begin
  MyStopWatch.Stop;
  Inc(acounter);
  if acounter mod 1000 = 0 then 
    allog('delay', FloatToStr(xStopWatch.Elapsed.TotalMilliseconds));
  MyStopWatch := TStopWatch.StartNew;
end;

当我启动应用程序时,OnTimer 事件每 10 毫秒而不是每 1 毫秒触发一次。 但是,如果我触摸屏幕并在屏幕上移动手指,该事件将改为每 1.3-1.5 毫秒触发一次。

谁能给我解释一下这种奇怪的行为?

为什么当我的手指触摸屏幕时,应用程序(或至少是计时器) react 更灵敏?如何使应用程序始终具有这种 react 性?

关于J..的言论

我认为这不是电池生命周期(但我不确定),因为如果我使用线程而不是像这样的计时器:

TThread.createAnonymousThread(
  procedure
  var MyStopWatch: TstopWatch;
      acounter: integer;
  begin

    acounter := 0;
    MyStopWatch :=  TStopWatch.StartNew;

    while True do begin
      TThread.synchronize(nil,
        procedure
        begin
          MyStopWatch.Stop;
          Inc(acounter);
          if acounter mod 1000 = 0 then
            allog('delay', FloatToStr(MyStopWatch.Elapsed.TotalMilliseconds));
          MyStopWatch := TStopWatch.StartNew;
        end);
      sleep(1);
    END;

  end).start;

然后一切正常,事件每 2 毫秒触发一次(没有每 1 毫秒 TThread.synchronize),并且这个手指是否在屏幕上。

最佳答案

与 VCL 的 TTimer 不同,FMX 在 Android 上的 TTimer 效率很低。

当计时器间隔结束时,Android 使用回调函数(在 Androidapi.Timer 单元中)通知 FMX。该回调由工作线程调用,并将计时器插入线程安全队列(在 FMX.Platform.Android 单元中)。

当主 UI 线程定期检查挂起的 UI 消息时,它还会检查计时器队列,如果有任何计时器排队,则调用它们的 OnTimer 事件处理程序(按照它们被调用的顺序)排队)。

但是,如果没有待处理的 UI 消息,FMX 可能会延迟检查计时器队列!然后,一旦处理完所有 UI 消息,再次处理事件之前可能会有延迟。这完全取决于 FMX 应用程序的内部状态。

因此,无法保证 1 毫秒计时器会在接近 1 毫秒间隔的任何地方触发其 OnTimer 事件处理程序。它还可以解释为什么 UI Activity 的增加可以让 OnTimer 事件更频繁地触发,因为 UI 消息被更频繁地处理。

这与VCL的TTimer不同,后者是基于WM_TIMER UI消息,是一个低优先级的消息,只有在没有其他UI消息时才会产生待办的。当它生成时,它会直接被分派(dispatch)到 TTimer 的内部窗口,没有额外的排队来增加额外的开销层。但是,UI Activity 的增加会减慢 TTImer.OnTimer 事件的触发速度,而不是加快它的速度。


TThread.Synchronize() 的情况下,每当需要处理挂起的同步请求时,它会主动通知主 UI 线程,从而允许主 UI 线程检查并执行同步'尽早完成程序。

关于android - 为什么当手指触摸屏幕时 Android 上的计时器更准确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45949296/

相关文章:

android - 使用具有更高 minSdkVersion 的库

android - 调整viewpager里面的view size,弥补tab height

html - 关于性能的分区与表格

function - 将继承的帧作为参数传递给过程

delphi - 使 TChromium 渲染抗锯齿

android - 任务 ':app:compileDebugJavaWithJavac' 执行失败。 > java.util.NoSuchElementException : List is empty

android - 管理堆大小

python - 当选择和更新都存在复杂条件时,更新数据框的最快方法是什么?

javascript - HTML5 <video> 标签性能

delphi - 当我移动项目时,导致 'hint' 在 ListView 上重新触发