diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK index 934b8ab21..83ad1fa4e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK @@ -25,6 +25,7 @@ android_library( react_native_dep('java/com/facebook/systrace:systrace'), react_native_dep('libraries/fbcore/src/main/java/com/facebook/common/logging:logging'), react_native_dep('libraries/soloader/java/com/facebook/soloader:soloader'), + react_native_dep('third-party/android/support/v4:lib-support-v4'), react_native_dep('third-party/java/infer-annotations:infer-annotations'), react_native_dep('third-party/java/jsr-305:jsr-305'), react_native_target('java/com/facebook/react/common:common'), @@ -33,4 +34,3 @@ android_library( 'PUBLIC', ], ) - diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java index 28ae53f36..7c88d5e8a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BaseJavaModule.java @@ -121,7 +121,7 @@ public abstract class BaseJavaModule implements NativeModule { @Override public Dynamic extractArgument( CatalystInstance catalystInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) { - return new DynamicFromArray(jsArguments, atIndex); + return DynamicFromArray.create(jsArguments, atIndex); } }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/Dynamic.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/Dynamic.java index efb66400b..19c87d110 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/Dynamic.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/Dynamic.java @@ -21,4 +21,5 @@ public interface Dynamic { ReadableArray asArray(); ReadableMap asMap(); ReadableType getType(); + void recycle(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromArray.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromArray.java index e215de5ea..26aa64e92 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromArray.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromArray.java @@ -9,51 +9,92 @@ package com.facebook.react.bridge; +import javax.annotation.Nullable; + +import android.support.v4.util.Pools; + /** * Implementation of Dynamic wrapping a ReadableArray. */ public class DynamicFromArray implements Dynamic { + private static final Pools.SimplePool sPool = new Pools.SimplePool<>(10); - private final ReadableArray mArray; - private final int mIndex; + private @Nullable ReadableArray mArray; + private int mIndex = -1; - public DynamicFromArray(ReadableArray array, int index) { - mArray = array; - mIndex = index; + // This is a pools object. Hide the constructor. + private DynamicFromArray() {} + + public static DynamicFromArray create(ReadableArray array, int index) { + DynamicFromArray dynamic = sPool.acquire(); + if (dynamic == null) { + dynamic = new DynamicFromArray(); + } + dynamic.mArray = array; + dynamic.mIndex = index; + return dynamic; + } + + @Override + public void recycle() { + mArray = null; + mIndex = -1; + sPool.release(this); } @Override public boolean asBoolean() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getBoolean(mIndex); } @Override public double asDouble() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getDouble(mIndex); } @Override public int asInt() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getInt(mIndex); } @Override public String asString() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getString(mIndex); } @Override public ReadableArray asArray() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getArray(mIndex); } @Override public ReadableMap asMap() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getMap(mIndex); } @Override public ReadableType getType() { + if (mArray == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mArray.getType(mIndex); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromMap.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromMap.java index e6be260ff..803964be1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromMap.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/DynamicFromMap.java @@ -9,51 +9,92 @@ package com.facebook.react.bridge; +import javax.annotation.Nullable; + +import android.support.v4.util.Pools; + /** * Implementation of Dynamic wrapping a ReadableMap. */ public class DynamicFromMap implements Dynamic { + private static final Pools.SimplePool sPool = new Pools.SimplePool<>(10); - private final ReadableMap mMap; - private final String mName; + private @Nullable ReadableMap mMap; + private @Nullable String mName; - public DynamicFromMap(ReadableMap map, String name) { - mMap = map; - mName = name; + // This is a pools object. Hide the constructor. + private DynamicFromMap() {} + + public static DynamicFromMap create(ReadableMap map, String name) { + DynamicFromMap dynamic = sPool.acquire(); + if (dynamic == null) { + dynamic = new DynamicFromMap(); + } + dynamic.mMap = map; + dynamic.mName = name; + return dynamic; + } + + @Override + public void recycle() { + mMap = null; + mName = null; + sPool.release(this); } @Override public boolean asBoolean() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getBoolean(mName); } @Override public double asDouble() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getDouble(mName); } @Override public int asInt() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getInt(mName); } @Override public String asString() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getString(mName); } @Override public ReadableArray asArray() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getArray(mName); } @Override public ReadableMap asMap() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getMap(mName); } @Override public ReadableType getType() { + if (mMap == null || mName == null) { + throw new IllegalStateException("This dynamic value has been recycled"); + } return mMap.getType(mName); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java index 680f49d39..cdabc82b9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyArray.java @@ -90,7 +90,7 @@ public class JavaOnlyArray implements ReadableArray, WritableArray { @Override public Dynamic getDynamic(int index) { - return new DynamicFromArray(this, index); + return DynamicFromArray.create(this, index); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java index 1b9ca0111..d5d953ba2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaOnlyMap.java @@ -90,7 +90,7 @@ public class JavaOnlyMap implements ReadableMap, WritableMap { @Override public Dynamic getDynamic(String name) { - return new DynamicFromMap(this, name); + return DynamicFromMap.create(this, name); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java index a0216d822..2fa8aa3a2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java @@ -49,7 +49,7 @@ public class ReadableNativeArray extends NativeArray implements ReadableArray { @Override public Dynamic getDynamic(int index) { - return new DynamicFromArray(this, index); + return DynamicFromArray.create(this, index); } public ArrayList toArrayList() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java index 87b6b1298..1eeaa07e3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java @@ -49,7 +49,7 @@ public class ReadableNativeMap extends NativeMap implements ReadableMap { @Override public Dynamic getDynamic(String name) { - return new DynamicFromMap(this, name); + return DynamicFromMap.create(this, name); } @Override