[android][utils] refactor legacy utils to use react natives own conversion utilities for performance

This commit is contained in:
Salakar 2018-05-06 00:51:54 +01:00
parent d5abd6a304
commit 3306d92f2d
2 changed files with 83 additions and 152 deletions

View File

@ -4,37 +4,24 @@ import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import javax.annotation.Nullable;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public class Utils { public class Utils {
private static final String TAG = "Utils"; private static final String TAG = "Utils";
// TODO NOTE
public static void todoNote(final String tag, final String name, final Callback callback) {
Log.e(tag, "The method " + name + " has not yet been implemented.");
Log.e(tag, "Feel free to contribute to finish the method in the source.");
WritableMap errorMap = Arguments.createMap();
errorMap.putString("error", "unimplemented");
callback.invoke(null, errorMap);
}
/** /**
* send a JS event * send a JS event
**/ **/
@ -49,162 +36,111 @@ public class Utils {
} }
/** /**
* @param key map key * Takes a value and calls the appropriate setter for its type on the target map + key
* @param value map value *
* @param map map * @param key String key to set on target map
* @param value Object value to set on target map
* @param map WritableMap target map to write the value to
*/ */
public static void mapPutValue(String key, Object value, WritableMap map) { @SuppressWarnings("unchecked")
String type = value != null ? value.getClass().getName() : ""; public static void mapPutValue(String key, @Nullable Object value, WritableMap map) {
switch (type) { if (value == null) {
case "java.lang.Boolean": map.putNull(key);
map.putBoolean(key, (Boolean) value); } else {
break; String type = value.getClass().getName();
case "java.lang.Long": switch (type) {
Long longVal = (Long) value; case "java.lang.Boolean":
map.putDouble(key, (double) longVal); map.putBoolean(key, (Boolean) value);
break; break;
case "java.lang.Float": case "java.lang.Long":
float floatVal = (float) value; Long longVal = (Long) value;
map.putDouble(key, (double) floatVal); map.putDouble(key, (double) longVal);
break; break;
case "java.lang.Double": case "java.lang.Float":
map.putDouble(key, (Double) value); float floatVal = (float) value;
break; map.putDouble(key, (double) floatVal);
case "java.lang.String": break;
map.putString(key, (String) value); case "java.lang.Double":
break; map.putDouble(key, (Double) value);
default: break;
map.putNull(key); case "java.lang.String":
map.putString(key, (String) value);
break;
default:
if (List.class.isAssignableFrom(value.getClass())) {
map.putArray(key, Arguments.makeNativeArray((List<Object>) value));
} else if (Map.class.isAssignableFrom(value.getClass())) {
map.putMap(key, Arguments.makeNativeMap((Map<String, Object>) value));
} else {
Log.d(TAG, "utils:mapPutValue:unknownType:" + type);
map.putNull(key);
}
}
} }
} }
/** /**
* @param map * Convert a ReadableMap to a WritableMap for the purposes of re-sending back to JS
* @return * TODO This is now a legacy util - internally uses RN functionality
*
* @param map ReadableMap
* @return WritableMap
*/ */
public static WritableMap readableMapToWritableMap(ReadableMap map) { public static WritableMap readableMapToWritableMap(ReadableMap map) {
WritableMap writableMap = Arguments.createMap(); WritableMap writableMap = Arguments.createMap();
// https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/WritableNativeMap.java#L54
ReadableMapKeySetIterator iterator = map.keySetIterator(); writableMap.merge(map);
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
ReadableType type = map.getType(key);
switch (type) {
case Null:
writableMap.putNull(key);
break;
case Boolean:
writableMap.putBoolean(key, map.getBoolean(key));
break;
case Number:
writableMap.putDouble(key, map.getDouble(key));
break;
case String:
writableMap.putString(key, map.getString(key));
break;
case Map:
writableMap.putMap(key, readableMapToWritableMap(map.getMap(key)));
break;
case Array:
// TODO writableMap.putArray(key, readableArrayToWritableArray(map.getArray(key)));
break;
default:
throw new IllegalArgumentException("Could not convert object with key: " + key + ".");
}
}
return writableMap; return writableMap;
} }
/**
* Convert a ReadableMap into a native Java Map
* TODO This is now a legacy util - internally uses RN functionality
*
* @param readableMap ReadableMap
* @return Map
*/
public static Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) { public static Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) {
Map<String, Object> deconstructedMap = new HashMap<>(); // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeMap.java#L216
if (readableMap == null) { return readableMap.toHashMap();
return deconstructedMap;
}
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
ReadableType type = readableMap.getType(key);
switch (type) {
case Null:
deconstructedMap.put(key, null);
break;
case Boolean:
deconstructedMap.put(key, readableMap.getBoolean(key));
break;
case Number:
deconstructedMap.put(key, readableMap.getDouble(key));
break;
case String:
deconstructedMap.put(key, readableMap.getString(key));
break;
case Map:
deconstructedMap.put(key, Utils.recursivelyDeconstructReadableMap(readableMap.getMap(key)));
break;
case Array:
deconstructedMap.put(key, Utils.recursivelyDeconstructReadableArray(readableMap.getArray(key)));
break;
default:
throw new IllegalArgumentException("Could not convert object with key: " + key + ".");
}
}
return deconstructedMap;
} }
/**
* Convert a ReadableArray into a native Java Map
* TODO This is now a legacy util - internally uses RN functionality
*
* @param readableArray ReadableArray
* @return List<Object>
*/
public static List<Object> recursivelyDeconstructReadableArray(ReadableArray readableArray) { public static List<Object> recursivelyDeconstructReadableArray(ReadableArray readableArray) {
List<Object> deconstructedList = new ArrayList<>(readableArray.size()); // https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.java#L175
for (int i = 0; i < readableArray.size(); i++) { return readableArray.toArrayList();
ReadableType indexType = readableArray.getType(i);
switch (indexType) {
case Null:
deconstructedList.add(i, null);
break;
case Boolean:
deconstructedList.add(i, readableArray.getBoolean(i));
break;
case Number:
deconstructedList.add(i, readableArray.getDouble(i));
break;
case String:
deconstructedList.add(i, readableArray.getString(i));
break;
case Map:
deconstructedList.add(i, Utils.recursivelyDeconstructReadableMap(readableArray.getMap(i)));
break;
case Array:
deconstructedList.add(i, Utils.recursivelyDeconstructReadableArray(readableArray.getArray(i)));
break;
default:
throw new IllegalArgumentException("Could not convert object at index " + i + ".");
}
}
return deconstructedList;
} }
/**
* We need to check if app is in foreground otherwise the app will crash.
* http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
*
* @param context Context
* @return boolean
*/
public static boolean isAppInForeground(Context context) { public static boolean isAppInForeground(Context context) {
/**
We need to check if app is in foreground otherwise the app will crash.
http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
**/
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = if (activityManager == null) return false;
activityManager.getRunningAppProcesses();
if (appProcesses == null) { List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
return false; if (appProcesses == null) return false;
}
final String packageName = context.getPackageName(); final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == if (
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
appProcess.processName.equals(packageName)) { && appProcess.processName.equals(packageName)
) {
return true; return true;
} }
} }
return false; return false;
} }
} }

View File

@ -6,7 +6,6 @@ import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator; import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.google.firebase.firestore.DocumentChange; import com.google.firebase.firestore.DocumentChange;
@ -18,15 +17,11 @@ import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.GeoPoint; import com.google.firebase.firestore.GeoPoint;
import com.google.firebase.firestore.QuerySnapshot; import com.google.firebase.firestore.QuerySnapshot;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import io.invertase.firebase.Utils; import io.invertase.firebase.Utils;