Try/catch the interpolator
diff --git a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java index 60aec53..dada31b 100644 --- a/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java +++ b/lottie/src/main/java/com/airbnb/lottie/parser/KeyframeParser.java
@@ -137,14 +137,23 @@ interpolator = interpolatorRef.get(); } if (interpolatorRef == null || interpolator == null) { - // If a control point extends beyond the previous/next point then it will cause the value of the interpolator to no - // longer monotonously increase. This clips the control point bounds to prevent that from happening. - // NOTE: this will make the rendered animation behave slightly differently than the original. - float cp1x = Math.min(cp1.x / scale, 1f); - float cp1y = Math.min(cp1.y / scale, 1f); - float cp2x = Math.max(cp2.x / scale, 0f); - float cp2y = Math.max(cp2.y / scale, 0f); - interpolator = PathInterpolatorCompat.create(cp1x, cp1y, cp2x, cp2y); + cp1.x /= scale; + cp1.y /= scale; + cp2.x /= scale; + cp2.y /= scale; + try { + interpolator = PathInterpolatorCompat.create(cp1.x, cp1.y, cp2.x, cp2.y); + } catch (IllegalArgumentException e) { + if (e.getMessage().equals("The Path cannot loop back on itself.")) { + // If a control point extends beyond the previous/next point then it will cause the value of the interpolator to no + // longer monotonously increase. This clips the control point bounds to prevent that from happening. + // NOTE: this will make the rendered animation behave slightly differently than the original. + interpolator = PathInterpolatorCompat.create(Math.min(cp1.x, 1f), cp1.y, Math.max(cp2.x, 0f), cp2.y); + } else { + // We failed to create the interpolator. Fall back to linear. + interpolator = new LinearInterpolator(); + } + } try { putInterpolator(hash, new WeakReference<>(interpolator)); } catch (ArrayIndexOutOfBoundsException e) {