Do Not Call a Recycled Android Resource
ID |
java.android_recycle_call |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
CWE:672, android, reliability |
Description
Reports method calls on Android recyclable resource variables (TypedArray, VelocityTracker, MotionEvent, Parcel) that occur after recycle() has already been called on the same variable. Accessing a recycled object is a use-after-free-style bug that may throw a runtime exception or produce undefined behaviour.
Rationale
Android recycles certain resource objects to reduce allocation pressure. Once recycle() has been called, the object’s internal state is released back to a pool and must not be accessed again.
VelocityTracker vt = VelocityTracker.obtain();
vt.addMovement(event);
vt.recycle();
// Bug: vt has been recycled -- this call is undefined
float xVel = vt.getXVelocity();
The getXVelocity() call after recycle() may throw an IllegalStateException, return stale data, or corrupt a pooled object that another component is already using.
Remediation
Ensure that no code path accesses the variable after recycle(). A common pattern is to null-out the reference immediately after recycling:
VelocityTracker vt = VelocityTracker.obtain();
try {
vt.addMovement(event);
vt.computeCurrentVelocity(1000);
float xVel = vt.getXVelocity();
} finally {
vt.recycle();
}
// vt is not accessed after recycle