private void playAnimation() {

        // Properly destroy a previous animation if it exists. This animation will only be non-null if it was
        // not interrupted.
        if (mPreviousAnimationInterrupted != null) {
            mPreviousAnimationInterrupted.dispose();
            mPreviousAnimationInterrupted = null;
        }

        // Terminate current animation if it allowed to be interrupted. Store current animation
        // in mPreviousAnimationInterrupted so that terminate() can run to completion in renderer thread.

        if (mState == AnimationState.RUNNING && mInterruptible == true) {
            mExecutableAnimation.terminate(!mInterruptible);
            mState = AnimationState.TERMINATED;
            mPreviousAnimationInterrupted = mExecutableAnimation;
            mExecutableAnimation = null;
        }

        if (mState == AnimationState.PAUSED) {
            mExecutableAnimation.resume();
            mState = AnimationState.RUNNING;
        }
        else if (mState == AnimationState.TERMINATED) {
            mState = AnimationState.SCHEDULED;
            // invoke startAnimation() right away if there is no delay provided.
            if (mDelayInMilliseconds <= 0) {
                startAnimation();
            } else {
                mMainLoopHandler.postDelayed(mDelayedRunner, (long) mDelayInMilliseconds);
            }
        }
        else {
            ViroLog.warn(TAG, "Unable to play animation in state " + mState.name());
        }
    }
This method sets us up to play the animation by scheduling a new animation or starting
a paused animation.
android/viro_bridge/src/main/java/com/viromedia/bridge/component/VRTManagedAnimation.java