diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/OnLayoutEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/OnLayoutEvent.java index f553858bd..393ccdf8d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/OnLayoutEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/OnLayoutEvent.java @@ -9,6 +9,9 @@ package com.facebook.react.uimanager; +import android.os.SystemClock; +import android.support.v4.util.Pools; + import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.events.Event; @@ -19,10 +22,30 @@ import com.facebook.react.uimanager.events.RCTEventEmitter; */ /* package */ class OnLayoutEvent extends Event { - private final int mX, mY, mWidth, mHeight; + private static final Pools.SynchronizedPool EVENTS_POOL = + new Pools.SynchronizedPool<>(20); - protected OnLayoutEvent(int viewTag, int x, int y, int width, int height) { - super(viewTag, 0); + private int mX, mY, mWidth, mHeight; + + public static OnLayoutEvent obtain(int viewTag, int x, int y, int width, int height) { + OnLayoutEvent event = EVENTS_POOL.acquire(); + if (event == null) { + event = new OnLayoutEvent(); + } + event.init(viewTag, x, y, width, height); + return event; + } + + @Override + public void onDispose() { + EVENTS_POOL.release(this); + } + + private OnLayoutEvent() { + } + + protected void init(int viewTag, int x, int y, int width, int height) { + super.init(viewTag, SystemClock.uptimeMillis()); mX = x; mY = y; mWidth = width; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index dd9b937e1..896e13c01 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -806,7 +806,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements // notify JS about layout event if requested if (cssNode.shouldNotifyOnLayout()) { mEventDispatcher.dispatchEvent( - new OnLayoutEvent( + OnLayoutEvent.obtain( tag, cssNode.getScreenX(), cssNode.getScreenY(), diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java index 505fea794..58dd958a6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java @@ -11,15 +11,31 @@ package com.facebook.react.uimanager.events; /** * A UI event that can be dispatched to JS. + * + * For dispatching events {@link EventDispatcher#dispatchEvent} should be used. Once event object + * is passed to the EventDispatched it should no longer be used as EventDispatcher may decide + * to recycle that object (by calling {@link #dispose}). */ public abstract class Event { - private final int mViewTag; - private final long mTimestampMs; + private boolean mInitialized; + private int mViewTag; + private long mTimestampMs; + + protected Event() { + } protected Event(int viewTag, long timestampMs) { + init(viewTag, timestampMs); + } + + /** + * This method needs to be called before event is sent to event dispatcher. + */ + protected void init(int viewTag, long timestampMs) { mViewTag = viewTag; mTimestampMs = timestampMs; + mInitialized = true; } /** @@ -68,7 +84,16 @@ public abstract class Event { * Called when the EventDispatcher is done with an event, either because it was dispatched or * because it was coalesced with another Event. */ - public void dispose() { + public void onDispose() { + } + + /*package*/ boolean isInitialized() { + return mInitialized; + } + + /*package*/ final void dispose() { + mInitialized = false; + onDispose(); } /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcher.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcher.java index aa3315c16..35c0a2897 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcher.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcher.java @@ -110,6 +110,7 @@ public class EventDispatcher implements LifecycleEventListener { * Sends the given Event to JS, coalescing eligible events if JS is backed up. */ public void dispatchEvent(Event event) { + Assertions.assertCondition(event.isInitialized(), "Dispatched event hasn't been initialized"); synchronized (mEventsStagingLock) { mEventStaging.add(event); } 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 26569f501..8bfe1f00a 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 @@ -96,7 +96,7 @@ public class TouchEvent extends Event { } @Override - public void dispose() { + public void onDispose() { mMotionEvent.recycle(); } }