{"record":{"id":"16d450c2ecc4d249","repo":"daimajia/AndroidViewAnimations","slug":"can-not-init-animatorclazz-instance","errorCode":null,"errorMessage":"Can not init animatorClazz instance","messagePattern":"Can not init animatorClazz instance","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"library/src/main/java/com/daimajia/androidanimations/library/Techniques.java","lineNumber":181,"sourceCode":"    ZoomOut(ZoomOutAnimator.class),\n    ZoomOutDown(ZoomOutDownAnimator.class),\n    ZoomOutLeft(ZoomOutLeftAnimator.class),\n    ZoomOutRight(ZoomOutRightAnimator.class),\n    ZoomOutUp(ZoomOutUpAnimator.class);\n\n\n\n    private Class animatorClazz;\n\n    private Techniques(Class clazz) {\n        animatorClazz = clazz;\n    }\n\n    public BaseViewAnimator getAnimator() {\n        try {\n            return (BaseViewAnimator) animatorClazz.newInstance();\n        } catch (Exception e) {\n            throw new Error(\"Can not init animatorClazz instance\");\n        }\n    }\n}\n","sourceCodeStart":163,"sourceCodeEnd":185,"githubUrl":"https://github.com/daimajia/AndroidViewAnimations/blob/6a35c466d23e49c5cd174289ebe8d9ccdbc69044/library/src/main/java/com/daimajia/androidanimations/library/Techniques.java#L163-L185","documentation":"YoYo's Techniques enum entries each point to a Class object (animatorClazz) of a BaseViewAnimator subclass. getAnimator() reflectively instantiates it with Class.newInstance(); this Error is a catch-all rethrow of any failure during that reflective instantiation (no public no-arg constructor, wrong visibility, or an exception in the class's <clinit> or constructor). It is thrown as a hard java.lang.Error, not a RuntimeException, because at that point the library assumes its internal animation classes are well-formed.","triggerScenarios":"Calling YoYo.with(Techniques.X) and letting it call getAnimator() when the resolved animator class cannot be reflectively instantiated: (1) the class has no public no-arg constructor, (2) the class is non-public/abstract or its constructor throws during animation setup, (3) the Class object does not actually extend BaseViewAnimator so the cast fails, (4) instantiation fails due to class-initializer errors (e.g. missing/renamed resources under a shrunk package).","commonSituations":"ProGuard/R8 obfuscation stripping or renaming animator subclasses so newInstance() fails at runtime; a forked/custom Technique added without a public no-arg constructor; library version changes that removed or renamed animator classes; animator static initialization throwing in certain device/theme environments.","solutions":["Do not obfuscate library animation classes: add ProGuard/R8 keep rules like -keep class com.daimajia.androidanimations.library.** { *; }","If you registered a custom Technique, make its animator class public with an explicit public no-arg constructor","Sync/upgrade the library version so animator classes match the Techniques enum entries (clean resolution: ./gradlew --refresh-dependencies)","Catch the Error at the call site and fall back to a safe animation (e.g. Techniques.FadeIn) or no animation","Reproduce with the reflective call wrapped in try/catch to log the original Exception 'e' — this error discards the root cause"],"exampleFix":"// before\npublic class MyAnimator extends BaseViewAnimator {\n    private MyAnimator() {} // private ctor -> newInstance() fails\n}\n// after\npublic class MyAnimator extends BaseViewAnimator {\n    public MyAnimator() {} // public no-arg ctor, required for reflection\n}","handlingStrategy":"try-catch","validationCode":"// Sanity-check that the animator is reflectively instantiable before composing:\ntry {\n    Object o = Techniques.FadeIn.getClass();\n    // If you hold the animator Class yourself, verify:\n    // Class<?> c = MyAnimator.class;\n    // c.getDeclaredConstructor(); // throws if no no-arg ctor\n} catch (Throwable t) {\n    android.util.Log.w(\"YoYo\", \"Animator not instantiable\", t);\n}","typeGuard":"// Java: verify the class hierarchy and modifiers before trusting a Technique's animator\nstatic boolean isValidAnimator(Class<?> clazz) {\n    return clazz != null\n        && BaseViewAnimator.class.isAssignableFrom(clazz)\n        && java.lang.reflect.Modifier.isPublic(clazz.getModifiers())\n        && !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers());\n}","tryCatchPattern":"try {\n    YoYo.with(Techniques.Bounce).duration(700).playOn(view);\n} catch (Error e) { // getAnimator throws java.lang.Error\n    Log.w(\"YoYo\", \"animation failed to init, skipping\", e);\n    // optional fallback:\n    // YoYo.with(Techniques.FadeIn).duration(300).playOn(view);\n}","preventionTips":["Add keep rules for com.daimajia.androidanimations.library.** in ProGuard/R8 configs","Never use animator classes with private or absent no-arg constructors","Test animations in a minified release build, not only debug, before shipping","Prefer built-in Techniques enum entries over hand-crafted custom ones","Keep the library version consistent across modules to avoid enum/class drift"],"tags":["reflection","instantiation","android","proguard"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6a35c466d23e49c5cd174289ebe8d9ccdbc69044","analyzedAt":"2026-09-08T03:31:43.217Z","contentChangedAt":"2026-09-08T03:31:43.217Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}