public final class Choreographer extends Object
The choreographer receives timing pulses (such as vertical synchronization) from the display subsystem then schedules work to occur as part of rendering the next display frame.
Applications typically interact with the choreographer indirectly using higher level abstractions in the animation framework or the view hierarchy. Here are some examples of things you can do using the higher-level APIs.
ValueAnimator.start(boolean)
.Runnable
to be invoked once at the beginning of the next display
frame, use View.postOnAnimation(java.lang.Runnable)
.Runnable
to be invoked once at the beginning of the next display
frame after a delay, use View.postOnAnimationDelayed(java.lang.Runnable, long)
.View.invalidate()
to occur once at the beginning of the
next display frame, use View.postInvalidateOnAnimation()
or
View.postInvalidateOnAnimation(int, int, int, int)
.View
scroll smoothly and are drawn in
sync with display frame rendering, do nothing. This already happens automatically.
View.onDraw(android.graphics.Canvas)
will be called at the appropriate time.However, there are a few cases where you might want to use the functions of the choreographer directly in your application. Here are some examples.
postFrameCallback(android.view.Choreographer.FrameCallback)
.
Each Looper
thread has its own choreographer. Other threads can
post callbacks to run on the choreographer but they will run on the Looper
to which the choreographer belongs.
Modifier and Type | Class and Description |
---|---|
static interface |
Choreographer.FrameCallback
Implement this interface to receive a callback when a new display frame is
being rendered.
|
Modifier and Type | Field and Description |
---|---|
static int |
CALLBACK_ANIMATION
Callback type: Animation callback.
|
static int |
CALLBACK_COMMIT
Callback type: Commit callback.
|
static int |
CALLBACK_INPUT
Callback type: Input callback.
|
static int |
CALLBACK_TRAVERSAL
Callback type: Traversal callback.
|
Modifier and Type | Method and Description |
---|---|
static long |
getFrameDelay()
The amount of time, in milliseconds, between each frame of the animation.
|
long |
getFrameIntervalNanos() |
long |
getFrameTime()
Gets the time when the current frame started.
|
long |
getFrameTimeNanos()
Same as
getFrameTime() but with nanosecond precision. |
static Choreographer |
getInstance()
Gets the choreographer for the calling thread.
|
void |
postCallback(int callbackType,
Runnable action,
Object token)
Posts a callback to run on the next frame.
|
void |
postCallbackDelayed(int callbackType,
Runnable action,
Object token,
long delayMillis)
Posts a callback to run on the next frame after the specified delay.
|
void |
postFrameCallback(Choreographer.FrameCallback callback)
Posts a frame callback to run on the next frame.
|
void |
postFrameCallbackDelayed(Choreographer.FrameCallback callback,
long delayMillis)
Posts a frame callback to run on the next frame after the specified delay.
|
static void |
releaseInstance()
Destroys the calling thread's choreographer
|
void |
removeCallbacks(int callbackType,
Runnable action,
Object token)
Removes callbacks that have the specified action and token.
|
void |
removeFrameCallback(Choreographer.FrameCallback callback)
Removes a previously posted frame callback.
|
static void |
setFrameDelay(long frameDelay)
The amount of time, in milliseconds, between each frame of the animation.
|
static long |
subtractFrameDelay(long delayMillis)
Subtracts typical frame delay time from a delay interval in milliseconds.
|
public static final int CALLBACK_INPUT
public static final int CALLBACK_ANIMATION
public static final int CALLBACK_TRAVERSAL
public static final int CALLBACK_COMMIT
frame time
reported
during this callback may be updated to reflect delays that occurred while
traversals were in progress in case heavy layout operations caused some frames
to be skipped. The frame time reported during this callback provides a better
estimate of the start time of the frame in which animations (and other updates
to the view hierarchy state) actually took effect.public static Choreographer getInstance()
Looper
associated with it.IllegalStateException
- if the thread does not have a looper.public static void releaseInstance()
public static long getFrameDelay()
This is a requested time that the animation will attempt to honor, but the actual delay between frames may be different, depending on system load and capabilities. This is a static function because the same delay will be applied to all animations, since they are all run off of a single timing loop.
The frame delay may be ignored when the animation system uses an external timing source, such as the display refresh rate (vsync), to govern animations.
public static void setFrameDelay(long frameDelay)
This is a requested time that the animation will attempt to honor, but the actual delay between frames may be different, depending on system load and capabilities. This is a static function because the same delay will be applied to all animations, since they are all run off of a single timing loop.
The frame delay may be ignored when the animation system uses an external timing source, such as the display refresh rate (vsync), to govern animations.
frameDelay
- the requested time between frames, in millisecondspublic static long subtractFrameDelay(long delayMillis)
This method can be used to compensate for animation delay times that have baked
in assumptions about the frame delay. For example, it's quite common for code to
assume a 60Hz frame time and bake in a 16ms delay. When we call
#postAnimationCallbackDelayed
we want to know how long to wait before
posting the animation callback but let the animation timer take care of the remaining
frame delay time.
This method is somewhat conservative about how much of the frame delay it
subtracts. It uses the same value returned by getFrameDelay()
which by
default is 10ms even though many parts of the system assume 16ms. Consequently,
we might still wait 6ms before posting an animation callback that we want to run
on the next frame, but this is much better than waiting a whole 16ms and likely
missing the deadline.
delayMillis
- The original delay time including an assumed frame delay.public long getFrameIntervalNanos()
public void postCallback(int callbackType, Runnable action, Object token)
The callback runs once then is automatically removed.
callbackType
- The callback type.action
- The callback action to run during the next frame.token
- The callback token, or null if none.removeCallbacks(int, java.lang.Runnable, java.lang.Object)
public void postCallbackDelayed(int callbackType, Runnable action, Object token, long delayMillis)
The callback runs once then is automatically removed.
callbackType
- The callback type.action
- The callback action to run during the next frame after the specified delay.token
- The callback token, or null if none.delayMillis
- The delay time in milliseconds.#removeCallback
public void removeCallbacks(int callbackType, Runnable action, Object token)
callbackType
- The callback type.action
- The action property of the callbacks to remove, or null to remove
callbacks with any action.token
- The token property of the callbacks to remove, or null to remove
callbacks with any token.postCallback(int, java.lang.Runnable, java.lang.Object)
,
postCallbackDelayed(int, java.lang.Runnable, java.lang.Object, long)
public void postFrameCallback(Choreographer.FrameCallback callback)
The callback runs once then is automatically removed.
callback
- The frame callback to run during the next frame.postFrameCallbackDelayed(android.view.Choreographer.FrameCallback, long)
,
removeFrameCallback(android.view.Choreographer.FrameCallback)
public void postFrameCallbackDelayed(Choreographer.FrameCallback callback, long delayMillis)
The callback runs once then is automatically removed.
callback
- The frame callback to run during the next frame.delayMillis
- The delay time in milliseconds.postFrameCallback(android.view.Choreographer.FrameCallback)
,
removeFrameCallback(android.view.Choreographer.FrameCallback)
public void removeFrameCallback(Choreographer.FrameCallback callback)
callback
- The frame callback to remove.postFrameCallback(android.view.Choreographer.FrameCallback)
,
postFrameCallbackDelayed(android.view.Choreographer.FrameCallback, long)
public long getFrameTime()
This method provides the time in milliseconds when the frame started being rendered.
The frame time provides a stable time base for synchronizing animations
and drawing. It should be used instead of SystemClock.uptimeMillis()
or System.nanoTime()
for animations and drawing in the UI. Using the frame
time helps to reduce inter-frame jitter because the frame time is fixed at the time
the frame was scheduled to start, regardless of when the animations or drawing
callback actually runs. All callbacks that run as part of rendering a frame will
observe the same frame time so using the frame time also helps to synchronize effects
that are performed by different callbacks.
Please note that the framework already takes care to process animations and drawing using the frame time as a stable time base. Most applications should not need to use the frame time information directly.
This method should only be called from within a callback.
SystemClock.uptimeMillis()
time base.IllegalStateException
- if no frame is in progress.public long getFrameTimeNanos()
getFrameTime()
but with nanosecond precision.System.nanoTime()
time base.IllegalStateException
- if no frame is in progress.