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

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