In my app I have a custom implementation of a drawer layout. It works fine on Android 2.3 & 4.0.4 but on Android 4.4 it crashes almost every time I open or close the drawer. Here is the error log :
E/AndroidRuntime( 9839): FATAL EXCEPTION: main
E/AndroidRuntime( 9839): Process: com.andryr.launcher, PID: 9839
E/AndroidRuntime( 9839): java.lang.IllegalStateException: Already in the pool!
E/AndroidRuntime( 9839): at android.util.Pools$SimplePool.release(Pools.java:112)
E/AndroidRuntime( 9839): at android.util.Pools$SynchronizedPool.release(Pools.java:161)
E/AndroidRuntime( 9839): at android.view.VelocityTracker.recycle(VelocityTracker.java:85)
E/AndroidRuntime( 9839): at com.andryr.widget.DrawerLayout.onTouchEvent(DrawerLayout.java:131)
E/AndroidRuntime( 9839): at android.view.View.dispatchTouchEvent(View.java:7706)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
E/AndroidRuntime( 9839): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
E/AndroidRuntime( 9839): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
E/AndroidRuntime( 9839): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
E/AndroidRuntime( 9839): at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
E/AndroidRuntime( 9839): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
E/AndroidRuntime( 9839): at android.view.View.dispatchPointerEvent(View.java:7886)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3947)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3826)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3518)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3575)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5532)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5512)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5483)
E/AndroidRuntime( 9839): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5612)
E/AndroidRuntime( 9839): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
E/AndroidRuntime( 9839): at android.os.MessageQueue.nativePollOnce(Native Method)
E/AndroidRuntime( 9839): at android.os.MessageQueue.next(MessageQueue.java:138)
E/AndroidRuntime( 9839): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 9839): at android.app.ActivityThread.main(ActivityThread.java:5001)
E/AndroidRuntime( 9839): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 9839): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
E/AndroidRuntime( 9839): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
and here is my code :
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if(!mInterceptTouchEvent)
{
return false;
}
if (ev.getAction() == MotionEvent.ACTION_DOWN
&& ((ev.getX() < ViewConfiguration.get(getContext())
.getScaledEdgeSlop() && !mExpanded) || (ev.getX() > getWidth()
- ViewConfiguration.get(getContext())
.getScaledEdgeSlop())
&& mExpanded))
{
if (mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
else
mVelocityTracker.clear();
return true;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
if(!mInterceptTouchEvent)
{
return false;
}
mLastMotionX = ev.getX();
if (mVelocityTracker == null)
return false;
switch (ev.getAction())
{
case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
mVelocity = mVelocityTracker.getXVelocity();
// ViewHelper.setTranslationX(mDrawerLayout,
// -mDrawerLayout.getWidth()
// + mLastMotionX);
// ViewHelper.setTranslationX(mRootView, mLastMotionX);
mPosition = (int) (-mDrawerLayout.getWidth() + mLastMotionX);
requestLayout();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (Math.abs(mVelocity) > ViewConfiguration.get(getContext())
.getScaledMinimumFlingVelocity()
&& Math.abs(mVelocity) < ViewConfiguration
.get(getContext()).getScaledMaximumFlingVelocity())
{
if (mVelocity > 0)
{
openDrawer();
} else
{
closeDrawer();
}
} else
{
if (mLastMotionX > getWidth() / 2)
{
openDrawer();
} else
{
closeDrawer();
}
}
mVelocityTracker.recycle();
return false;
}
return true;
}
line 131 is :
mVelocityTracker.recycle();
I don't understand why is this happening.
I had to set my velocitytracker to null after recycling it to make it work porperly
As metioned in the docs here, you have to call velocityTracker.clear()
if you want to use it again.
Use velocityTracker.recycle()
if you will not use the object again- to free up resources. Do this when your activity is being destroyed.
(That's why the accepted answer by @andryr works. You are creating a new one)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With