Tencent/QMUI_Android · error · IllegalAccessError
don't call #onEnterAnimationStart() directly
Error message
don't call #onEnterAnimationStart() directly
What it means
QMUIFragment.onEnterAnimationStart() is a lifecycle callback invoked by the framework when the fragment's enter animation begins. It uses a mCalled flag so that invoking it manually is detected; a second/direct call throws IllegalAccessError because the enter-animation status (mEnterAnimationStatus, isInEnterAnimationLiveData) would be corrupted by duplicate invocation.
Source
Thrown at arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java:1395
public void runAfterResumed(Runnable runnable) {
Utils.assertInMainThread();
if (isResumed()) {
runnable.run();
} else {
if (mPostResumeRunnableList == null) {
mPostResumeRunnableList = new ArrayList<>(4);
}
mPostResumeRunnableList.add(runnable);
}
}
/**
* may not be call.
* @param animation
*/
protected void onEnterAnimationStart(@Nullable Animator animation) {
if (mCalled) {
throw new IllegalAccessError("don't call #onEnterAnimationStart() directly");
}
mCalled = true;
mEnterAnimationStatus = ANIMATION_ENTER_STATUS_STARTED;
isInEnterAnimationLiveData.setValue(true);
}
/**
* may not be call.
* @param animation
*/
protected void onEnterAnimationEnd(@Nullable Animator animation) {
if (mCalled) {
throw new IllegalAccessError("don't call #onEnterAnimationEnd() directly");
}
mCalled = true;
mEnterAnimationStatus = ANIMATION_ENTER_STATUS_END;
isInEnterAnimationLiveData.setValue(false);
notifyDelayRenderRunnableList();View on GitHub (pinned to 026e7d4866)
Solutions
- Remove any direct call to onEnterAnimationStart(); let QMUIFragment's internal animation dispatch call it.
- If you need to hook the enter animation, override onEnterAnimationStart() in your fragment subclass and call super, instead of invoking it externally.
- Trigger animation-driven behavior via the public fragment transition APIs (e.g. startFragment/postAnimateShow) rather than the callback.
- For testing, verify the callback fired by observing isInEnterAnimationLiveData instead of calling it.
Example fix
// before
fragment.onEnterAnimationStart(animator);
// after
@Override
protected void onEnterAnimationStart(@Nullable Animator animation) {
super.onEnterAnimationStart(animation);
// custom logic here
} Defensive patterns
Strategy: validation
Validate before calling
if (fragment instanceof QMUIFragment) {
// never call onEnterAnimationStart directly; rely on framework dispatch
} Type guard
boolean isFrameworkLifecycleHook(Method m) {
return m != null && java.lang.reflect.Modifier.isProtected(m.getModifiers())
&& m.getName().startsWith("onEnterAnimation");
} Prevention
- Never invoke protected lifecycle callbacks (onEnterAnimationStart/End) from app code
- Override the hooks and call super instead of calling them externally
- Trigger transitions through public QMUI navigation APIs
- Observe isInEnterAnimationLiveData for animation state
When it happens
Trigger: Calling fragment.onEnterAnimationStart(animator) directly from app code, or invoking it twice (the mCalled flag is not reset between calls in the visible region), or subclass code invoking super/onEnterAnimationStart outside the framework dispatch path.
Common situations: Developers trying to manually trigger enter-animation behavior, custom animation orchestration that re-fires the callback, or reflection-based testing that calls protected lifecycle hooks directly.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- don't call #onEnterAnimationEnd() directly
- View is not attached to window
- can not perform $action when running.
- Can not perform LatestVisitRecord, %s must be annotated by L
- Fragment(%s) not attached to Activity.
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/302e3996e19fb4c3.
Report an issue: GitHub.