am 13b27810: Merge "Remove unnecessary reflection lookup in Animators." into lmp-mr1-dev

* commit '13b27810f990ea57decfcde98ddd461b8c0b9936':
  Remove unnecessary reflection lookup in Animators.
This commit is contained in:
George Mount
2014-11-12 15:45:15 +00:00
committed by Android Git Automerger

View File

@@ -105,10 +105,6 @@ public class PropertyValuesHolder implements Cloneable {
private static final HashMap<Class, HashMap<String, Method>> sGetterPropertyMap =
new HashMap<Class, HashMap<String, Method>>();
// This lock is used to ensure that only one thread is accessing the property maps
// at a time.
final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock();
// Used to pass single value to varargs parameter in setter invocation
final Object[] mTmpValueArray = new Object[1];
@@ -737,16 +733,19 @@ public class PropertyValuesHolder implements Cloneable {
HashMap<Class, HashMap<String, Method>> propertyMapMap,
String prefix, Class valueType) {
Method setterOrGetter = null;
try {
synchronized(propertyMapMap) {
// Have to lock property map prior to reading it, to guard against
// another thread putting something in there after we've checked it
// but before we've added an entry to it
mPropertyMapLock.writeLock().lock();
HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass);
boolean wasInMap = false;
if (propertyMap != null) {
setterOrGetter = propertyMap.get(mPropertyName);
wasInMap = propertyMap.containsKey(mPropertyName);
if (wasInMap) {
setterOrGetter = propertyMap.get(mPropertyName);
}
}
if (setterOrGetter == null) {
if (!wasInMap) {
setterOrGetter = getPropertyFunction(targetClass, prefix, valueType);
if (propertyMap == null) {
propertyMap = new HashMap<String, Method>();
@@ -754,8 +753,6 @@ public class PropertyValuesHolder implements Cloneable {
}
propertyMap.put(mPropertyName, setterOrGetter);
}
} finally {
mPropertyMapLock.writeLock().unlock();
}
return setterOrGetter;
}
@@ -811,30 +808,33 @@ public class PropertyValuesHolder implements Cloneable {
mProperty = null;
}
}
Class targetClass = target.getClass();
if (mSetter == null) {
setupSetter(targetClass);
}
List<Keyframe> keyframes = mKeyframes.getKeyframes();
int keyframeCount = keyframes == null ? 0 : keyframes.size();
for (int i = 0; i < keyframeCount; i++) {
Keyframe kf = keyframes.get(i);
if (!kf.hasValue() || kf.valueWasSetOnStart()) {
if (mGetter == null) {
setupGetter(targetClass);
// We can't just say 'else' here because the catch statement sets mProperty to null.
if (mProperty == null) {
Class targetClass = target.getClass();
if (mSetter == null) {
setupSetter(targetClass);
}
List<Keyframe> keyframes = mKeyframes.getKeyframes();
int keyframeCount = keyframes == null ? 0 : keyframes.size();
for (int i = 0; i < keyframeCount; i++) {
Keyframe kf = keyframes.get(i);
if (!kf.hasValue() || kf.valueWasSetOnStart()) {
if (mGetter == null) {
// Already logged the error - just return to avoid NPE
return;
setupGetter(targetClass);
if (mGetter == null) {
// Already logged the error - just return to avoid NPE
return;
}
}
try {
Object value = convertBack(mGetter.invoke(target));
kf.setValue(value);
kf.setValueWasSetOnStart(true);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
try {
Object value = convertBack(mGetter.invoke(target));
kf.setValue(value);
kf.setValueWasSetOnStart(true);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
} catch (IllegalAccessException e) {
Log.e("PropertyValuesHolder", e.toString());
}
}
}
@@ -1178,32 +1178,33 @@ public class PropertyValuesHolder implements Cloneable {
return;
}
// Check new static hashmap<propName, int> for setter method
try {
mPropertyMapLock.writeLock().lock();
synchronized(sJNISetterPropertyMap) {
HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
boolean wasInMap = false;
if (propertyMap != null) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
}
if (mJniSetter == 0) {
String methodName = getMethodName("set", mPropertyName);
mJniSetter = nGetIntMethod(targetClass, methodName);
if (mJniSetter != 0) {
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
wasInMap = propertyMap.containsKey(mPropertyName);
if (wasInMap) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
propertyMap.put(mPropertyName, mJniSetter);
}
}
} catch (NoSuchMethodError e) {
// Couldn't find it via JNI - try reflection next. Probably means the method
// doesn't exist, or the type is wrong. An error will be logged later if
// reflection fails as well.
} finally {
mPropertyMapLock.writeLock().unlock();
if (!wasInMap) {
String methodName = getMethodName("set", mPropertyName);
try {
mJniSetter = nGetIntMethod(targetClass, methodName);
} catch (NoSuchMethodError e) {
// Couldn't find it via JNI - try reflection next. Probably means the method
// doesn't exist, or the type is wrong. An error will be logged later if
// reflection fails as well.
}
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, mJniSetter);
}
}
if (mJniSetter == 0) {
// Couldn't find method through fast JNI approach - just use reflection
@@ -1315,32 +1316,33 @@ public class PropertyValuesHolder implements Cloneable {
return;
}
// Check new static hashmap<propName, int> for setter method
try {
mPropertyMapLock.writeLock().lock();
synchronized (sJNISetterPropertyMap) {
HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
boolean wasInMap = false;
if (propertyMap != null) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
}
if (mJniSetter == 0) {
String methodName = getMethodName("set", mPropertyName);
mJniSetter = nGetFloatMethod(targetClass, methodName);
if (mJniSetter != 0) {
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
wasInMap = propertyMap.containsKey(mPropertyName);
if (wasInMap) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
propertyMap.put(mPropertyName, mJniSetter);
}
}
} catch (NoSuchMethodError e) {
// Couldn't find it via JNI - try reflection next. Probably means the method
// doesn't exist, or the type is wrong. An error will be logged later if
// reflection fails as well.
} finally {
mPropertyMapLock.writeLock().unlock();
if (!wasInMap) {
String methodName = getMethodName("set", mPropertyName);
try {
mJniSetter = nGetFloatMethod(targetClass, methodName);
} catch (NoSuchMethodError e) {
// Couldn't find it via JNI - try reflection next. Probably means the method
// doesn't exist, or the type is wrong. An error will be logged later if
// reflection fails as well.
}
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, mJniSetter);
}
}
if (mJniSetter == 0) {
// Couldn't find method through fast JNI approach - just use reflection
@@ -1419,16 +1421,19 @@ public class PropertyValuesHolder implements Cloneable {
if (mJniSetter != 0) {
return;
}
try {
mPropertyMapLock.writeLock().lock();
synchronized(sJNISetterPropertyMap) {
HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
boolean wasInMap = false;
if (propertyMap != null) {
Long jniSetterLong = propertyMap.get(mPropertyName);
if (jniSetterLong != null) {
mJniSetter = jniSetterLong;
wasInMap = propertyMap.containsKey(mPropertyName);
if (wasInMap) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
}
}
if (mJniSetter == 0) {
if (!wasInMap) {
String methodName = getMethodName("set", mPropertyName);
calculateValue(0f);
float[] values = (float[]) getAnimatedValue();
@@ -1437,19 +1442,20 @@ public class PropertyValuesHolder implements Cloneable {
mJniSetter = nGetMultipleFloatMethod(targetClass, methodName, numParams);
} catch (NoSuchMethodError e) {
// try without the 'set' prefix
mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName, numParams);
}
if (mJniSetter != 0) {
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
try {
mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName,
numParams);
} catch (NoSuchMethodError e2) {
// just try reflection next
}
propertyMap.put(mPropertyName, mJniSetter);
}
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, mJniSetter);
}
} finally {
mPropertyMapLock.writeLock().unlock();
}
}
}
}
@@ -1522,16 +1528,19 @@ public class PropertyValuesHolder implements Cloneable {
if (mJniSetter != 0) {
return;
}
try {
mPropertyMapLock.writeLock().lock();
synchronized(sJNISetterPropertyMap) {
HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
boolean wasInMap = false;
if (propertyMap != null) {
Long jniSetterLong = propertyMap.get(mPropertyName);
if (jniSetterLong != null) {
mJniSetter = jniSetterLong;
wasInMap = propertyMap.containsKey(mPropertyName);
if (wasInMap) {
Long jniSetter = propertyMap.get(mPropertyName);
if (jniSetter != null) {
mJniSetter = jniSetter;
}
}
}
if (mJniSetter == 0) {
if (!wasInMap) {
String methodName = getMethodName("set", mPropertyName);
calculateValue(0f);
int[] values = (int[]) getAnimatedValue();
@@ -1540,18 +1549,19 @@ public class PropertyValuesHolder implements Cloneable {
mJniSetter = nGetMultipleIntMethod(targetClass, methodName, numParams);
} catch (NoSuchMethodError e) {
// try without the 'set' prefix
mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName, numParams);
}
if (mJniSetter != 0) {
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
try {
mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName,
numParams);
} catch (NoSuchMethodError e2) {
// couldn't find it.
}
propertyMap.put(mPropertyName, mJniSetter);
}
if (propertyMap == null) {
propertyMap = new HashMap<String, Long>();
sJNISetterPropertyMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, mJniSetter);
}
} finally {
mPropertyMapLock.writeLock().unlock();
}
}
}