gpt4 book ai didi

android - 如何在移动设备上确定设备屏幕刷新开始/停止

转载 作者:行者123 更新时间:2023-11-29 18:34:05 25 4
gpt4 key购买 nike

在 60Hz 设备上,屏幕每 ~16.67 毫秒刷新一次(我看到这称为刷新率和翻转计数)。对于某些研究,这实际上是一个不错的时间。当屏幕刷新或开始刷新时,有什么方法可以获得准确的时间戳或事件?

最佳答案

在 iOS 上,您可以使用 CADisplayLink:https://developer.apple.com/documentation/quartzcore/cadisplaylink

A timer object that allows your application to synchronize its drawing to the refresh rate of the display.

例子:

import Foundation
import UIKit

public class DisplayFrameSync {
private var displayLink: CADisplayLink? = nil
private var frameUpdate: (() -> Void)? = nil

deinit {
self.stop()
}

@objc
private func onTick(displayLink: CADisplayLink) {
if let onFrameUpdate = self.frameUpdate {
onFrameUpdate()
}
}

public func start(_ update: () -> Void) {
self.displayLink?.remove(from: .main, forMode: .default)
self.displayLink?.remove(from: .main, forMode: .tracking)
self.displayLink?.invalidate()
self.displayLink = nil

self.frameUpdate = update

self.displayLink = CADisplayLink(target: self, selector: #selector(onTick(displayLink:)))
self.displayLink?.preferredFramesPerSecond = 60
self.displayLink?.add(to: .main, forMode: .default)
self.displayLink?.add(to: .main, forMode: .tracking)
}

public func stop() {
self.displayLink?.remove(from: .main, forMode: .default)
self.displayLink?.remove(from: .main, forMode: .tracking)
self.displayLink?.invalidate()
self.displayLink = nil
self.frameUpdate = nil
}
}

用法:

let ds = DisplayFrameSync()
ds.start({
print("Frame Update")
});

DispatchQueue.main.asyncAfter(.now() + 2.0) {
ds.stop()
}

使用上面的方法,您还可以制作自己的 animateWithDuration 并使用 Date.timeIntervalSinceReferenceDate 自己跟踪时间并从当前时间中减去每一帧。


对于 Android,您可以使用 Choreographer:

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Choreographer;

private class DisplayFrameSync extends Thread implements Choreographer.FrameCallback {
private volatile Handler signal;
private Consumer<Long> update;

public DisplayFrameSync(Consumer<Long> update) {
super();

this.update = update;
}

@Override
public void run() {
setName("DisplayFrameSyncThread");

Looper.prepare();

signal = new Handler() {
public void handleMessage(Message msg) {
Looper.myLooper().quit();
}
};

Choreographer.getInstance().postFrameCallback(this);

Looper.loop();
Choreographer.getInstance().removeFrameCallback(this);
}

public void signal() {
if (this.signal != null) {
this.signal.sendEmptyMessage(0);
this.signal = null;
}
}

@Override
public void doFrame(long timeNano) {
if (this.update != null) {
this.update.accept(timeNano);
}

Choreographer.getInstance().postFrameCallback(this);
}
}

这已经包含了每一帧渲染的时间..

用法:

DisplayFrameSync ds = new DisplayFrameSync((timeNano) -> {
System.out.println("Frame Update");
});
ds.start();

//Later..
ds.stop();

关于android - 如何在移动设备上确定设备屏幕刷新开始/停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55028881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com