我正在寻找一种方法来将某些代码活动与Android显示帧速率同步。这是一小段代码,只需设置一个小显示区域的颜色,仅此而已。是否有某种方法或钩子可以用于此目的?
我可以使用以非常快的间隔成功运行的计时器,但渲染似乎会受到帧速率的混叠。例如,我的帧速率为60 Hz,因此如果我将定时器间隔设置为1/60秒,则外观不均匀。我无法将定时器设置为16.666毫秒,即使可以,我仍然会看到别名。
感谢。
答案 0 :(得分:1)
经过一些搜索和实验,一个解决方案是使用Choreographer类,它提供了一种将回调函数挂钩到帧速率的方法。下面是代码。我发现它在慢速手机上显示出邋time的时机。近期型号的三星手机性能更佳。
private FrameCallback frameCallback = null;
private boolean frameCallbackPending = false;
public void armVSyncHandler() {
if(!frameCallbackPending) {
frameCallbackPending = true;
if(frameCallback == null)
{
frameCallback = new FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
frameCallbackPending = false;
// Do some work here
armVSyncHandler();
}
};
}
Choreographer.getInstance().postFrameCallback(frameCallback);
}
}
答案 1 :(得分:1)
我知道这是一个古老的问题,但是我自己遇到了这个问题,并创建了一个很好的小实用程序类来实现此目的。
科特琳课:
/**
* Small utility class that allows for [doFrame] to be executed every frame based on the native
* [Choreographer] instead of using precomputed values and timers.
* [doFrame] is run on the main thread and is executed on the next frame.
* The [SyncedRenderer] can be restarted freely.
*/
class SyncedRenderer(val doFrame: (frameTimeNanos: Long) -> Unit) {
private var callback: (Long) -> Unit = {}
fun start() {
callback = {
doFrame(it)
Choreographer.getInstance().postFrameCallback(callback)
}
Choreographer.getInstance().postFrameCallback(callback)
}
fun stop() {
Choreographer.getInstance().removeFrameCallback(callback)
callback = {}
}
}
用法:
val renderer = SyncedRenderer { frameTimeNanos: Long ->
// My code here will execute on main thread every frame
}
// Example when dragging something
override fun onStartDrag() {
renderer.start()
}
override fun onReleaseDrag() {
renderer.stop()
}
我发现与仅使用固定速率Timer
并以每帧刷新速率运行代码相比,它的性能仅高一点。
但是,通过此实现,您无需在背景线程上运行任何代码,因此在修改post
时无需调用任何类型的View
或它的相关方法。
更重要的是,尽管没有执行多余的执行工作,所以与使用硬编码刷新率计时器相比,这对于更平滑的滚动和动画制作非常有用。
希望这对某人有帮助:)