From 46e67ef42892270ad3dcf792192009e048246f2a Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Wed, 28 Oct 2015 02:11:09 -0700 Subject: [PATCH] Recycle touch events. Reviewed By: andreicoman11 Differential Revision: D2590149 fb-gh-sync-id: 97c60e12385526097431a192b692e2f92813722d --- .../com/facebook/react/ReactRootView.java | 12 +++--- .../react/uimanager/events/TouchEvent.java | 42 ++++++++++++++----- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index f7aeb89b4..5e21647df 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -145,7 +145,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView mChildIsHandlingNativeGesture = false; mTargetTag = TouchTargetHelper.findTargetTagForTouch(ev.getY(), ev.getX(), this); eventDispatcher.dispatchEvent( - new TouchEvent(mTargetTag, SystemClock.uptimeMillis(),TouchEventType.START, ev)); + TouchEvent.obtain(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.START, ev)); } else if (mChildIsHandlingNativeGesture) { // If the touch was intercepted by a child, we've already sent a cancel event to JS for this // gesture, so we shouldn't send any more touches related to it. @@ -161,20 +161,20 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView // End of the gesture. We reset target tag to -1 and expect no further event associated with // this gesture. eventDispatcher.dispatchEvent( - new TouchEvent(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.END, ev)); + TouchEvent.obtain(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.END, ev)); mTargetTag = -1; } else if (action == MotionEvent.ACTION_MOVE) { // Update pointer position for current gesture eventDispatcher.dispatchEvent( - new TouchEvent(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.MOVE, ev)); + TouchEvent.obtain(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.MOVE, ev)); } else if (action == MotionEvent.ACTION_POINTER_DOWN) { // New pointer goes down, this can only happen after ACTION_DOWN is sent for the first pointer eventDispatcher.dispatchEvent( - new TouchEvent(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.START, ev)); + TouchEvent.obtain(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.START, ev)); } else if (action == MotionEvent.ACTION_POINTER_UP) { // Exactly onw of the pointers goes up eventDispatcher.dispatchEvent( - new TouchEvent(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.END, ev)); + TouchEvent.obtain(mTargetTag, SystemClock.uptimeMillis(), TouchEventType.END, ev)); } else if (action == MotionEvent.ACTION_CANCEL) { dispatchCancelEvent(ev); mTargetTag = -1; @@ -219,7 +219,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView !mChildIsHandlingNativeGesture, "Expected to not have already sent a cancel for this gesture"); Assertions.assertNotNull(eventDispatcher).dispatchEvent( - new TouchEvent( + TouchEvent.obtain( mTargetTag, SystemClock.uptimeMillis(), TouchEventType.CANCEL, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java index 8bfe1f00a..10a4bda3a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java @@ -9,6 +9,7 @@ package com.facebook.react.uimanager.events; +import android.support.v4.util.Pools; import android.view.MotionEvent; /** @@ -21,16 +22,42 @@ import android.view.MotionEvent; */ public class TouchEvent extends Event { - private final MotionEvent mMotionEvent; - private final TouchEventType mTouchEventType; - private final short mCoalescingKey; + private static final Pools.SynchronizedPool EVENTS_POOL = + new Pools.SynchronizedPool<>(3); - public TouchEvent( + public static TouchEvent obtain( int viewTag, long timestampMs, TouchEventType touchEventType, MotionEvent motionEventToCopy) { - super(viewTag, timestampMs); + TouchEvent event = EVENTS_POOL.acquire(); + if (event == null) { + event = new TouchEvent(); + } + event.init(viewTag, timestampMs, touchEventType, motionEventToCopy); + return event; + } + + private MotionEvent mMotionEvent; + private TouchEventType mTouchEventType; + private short mCoalescingKey; + + private TouchEvent() { + } + + @Override + public void onDispose() { + mMotionEvent.recycle(); + mMotionEvent = null; + EVENTS_POOL.release(this); + } + + private void init( + int viewTag, + long timestampMs, + TouchEventType touchEventType, + MotionEvent motionEventToCopy) { + super.init(viewTag, timestampMs); mTouchEventType = touchEventType; mMotionEvent = MotionEvent.obtain(motionEventToCopy); @@ -94,9 +121,4 @@ public class TouchEvent extends Event { getViewTag(), mMotionEvent); } - - @Override - public void onDispose() { - mMotionEvent.recycle(); - } }