From d3449be65c07a22c8300bc4485b7cd0ecbfc4271 Mon Sep 17 00:00:00 2001 From: Ozodrukh Date: Sun, 28 Dec 2014 21:21:27 +0500 Subject: [PATCH 1/2] MethodNotFoundException fixed --- .../main/java/com/telly/mrvector/Utils.java | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/library/src/main/java/com/telly/mrvector/Utils.java b/library/src/main/java/com/telly/mrvector/Utils.java index 159464d..e8d3b00 100644 --- a/library/src/main/java/com/telly/mrvector/Utils.java +++ b/library/src/main/java/com/telly/mrvector/Utils.java @@ -22,8 +22,15 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.v4.graphics.drawable.DrawableCompat; import android.util.Log; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import static android.graphics.PorterDuff.Mode; import static android.graphics.PorterDuff.Mode.SRC_IN; import static android.os.Build.VERSION.SDK_INT; @@ -41,20 +48,25 @@ public class Utils { static final Mode DEFAULT_TINT_MODE = SRC_IN; static final boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP; - public static T tryInvoke(Object target, String methodName, Object... args) { - final int argsCount = args == null ? 0 : args.length; - Class[] argTypes = new Class[argsCount]; - for (int i = 0; i < argsCount; i++) { - argTypes[i] = args[i].getClass(); - } - - return tryInvoke(target, methodName, argTypes, args); - } + static Map sCachedMethods = new HashMap<>(); + static Class[][] sCachedArgsTypes = { + {int.class}, {PorterDuff.Mode.class}, {} + }; + @SuppressWarnings("unchecked") public static T tryInvoke(Object target, String methodName, Class[] argTypes, Object... args) { + try { - return (T) target.getClass().getDeclaredMethod(methodName, argTypes).invoke(target, args); + Method method = sCachedMethods.get(methodName); + if(method != null){ + return (T) method.invoke(target, args); + } + + method = target.getClass().getDeclaredMethod(methodName, argTypes); + sCachedMethods.put(methodName, method); + + return (T) method.invoke(target, args); } catch (Exception pokemon) { Log.e(LOGTAG, "Unable to invoke " + methodName + " on " + target, pokemon); } @@ -63,7 +75,7 @@ public static T tryInvoke(Object target, String methodName, Class[] argTy } static int getLayoutDirection(Drawable drawable) { - final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", (Object[])null); + final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", sCachedArgsTypes[2]); return layoutDirection == null ? LTR : layoutDirection.intValue(); } @@ -80,8 +92,14 @@ static Mode parseTintMode(int value, Mode defaultMode) { case 9: return Mode.SRC_ATOP; case 14: return Mode.MULTIPLY; case 15: return Mode.SCREEN; - case 16: return Mode.ADD; - default: return defaultMode; + + case 16: + if(Build.VERSION.SDK_INT > 11) { + return Mode.ADD; + } + + default: + return defaultMode; } } @@ -96,12 +114,13 @@ static PorterDuffColorFilter updateTintFilter(Drawable drawable, PorterDuffColor } final int color = tint.getColorForState(drawable.getState(), Color.TRANSPARENT); + if (tintFilter == null || !LOLLIPOP_PLUS) { // TODO worth caching them? return new PorterDuffColorFilter(color, tintMode); } - tryInvoke(tintFilter, "setColor", color); - tryInvoke(tintFilter, "setMode", tintMode); + tryInvoke(tintFilter, "setColor", sCachedArgsTypes[0], color); + tryInvoke(tintFilter, "setMode", sCachedArgsTypes[1],tintMode); return tintFilter; } From f56127c2b05d28724236e2269cdbfb73736f8fcf Mon Sep 17 00:00:00 2001 From: Ozodrukh Date: Tue, 30 Dec 2014 08:04:17 +0500 Subject: [PATCH 2/2] improve code quality --- .../main/java/com/telly/mrvector/Utils.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/library/src/main/java/com/telly/mrvector/Utils.java b/library/src/main/java/com/telly/mrvector/Utils.java index e8d3b00..c068e39 100644 --- a/library/src/main/java/com/telly/mrvector/Utils.java +++ b/library/src/main/java/com/telly/mrvector/Utils.java @@ -23,17 +23,17 @@ import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.os.Build; -import android.support.v4.graphics.drawable.DrawableCompat; +import android.support.v4.util.SimpleArrayMap; import android.util.Log; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import static android.graphics.PorterDuff.Mode; import static android.graphics.PorterDuff.Mode.SRC_IN; import static android.os.Build.VERSION.SDK_INT; +import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.LOLLIPOP; import static android.util.LayoutDirection.LTR; import static com.telly.mrvector.VectorDrawable.LOGTAG; @@ -47,11 +47,13 @@ public class Utils { */ static final Mode DEFAULT_TINT_MODE = SRC_IN; static final boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP; + static final boolean HONEYCOMB_PLUS = SDK_INT >= HONEYCOMB; - static Map sCachedMethods = new HashMap<>(); - static Class[][] sCachedArgsTypes = { - {int.class}, {PorterDuff.Mode.class}, {} - }; + static SimpleArrayMap sCachedMethods = new SimpleArrayMap<>(); + + final static Class[] INT_ARG = {int.class}; + final static Class[] MODE_ARG = {Mode.class}; + final static Class[] EMPTY_ARG = {}; @SuppressWarnings("unchecked") public static T tryInvoke(Object target, String methodName, Class[] argTypes, @@ -60,7 +62,7 @@ public static T tryInvoke(Object target, String methodName, Class[] argTy try { Method method = sCachedMethods.get(methodName); if(method != null){ - return (T) method.invoke(target, args); + return (T) method.invoke(target, args); } method = target.getClass().getDeclaredMethod(methodName, argTypes); @@ -75,7 +77,7 @@ public static T tryInvoke(Object target, String methodName, Class[] argTy } static int getLayoutDirection(Drawable drawable) { - final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", sCachedArgsTypes[2]); + final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", EMPTY_ARG); return layoutDirection == null ? LTR : layoutDirection.intValue(); } @@ -94,12 +96,12 @@ static Mode parseTintMode(int value, Mode defaultMode) { case 15: return Mode.SCREEN; case 16: - if(Build.VERSION.SDK_INT > 11) { - return Mode.ADD; - } + if(HONEYCOMB_PLUS) { + return Mode.ADD; + } default: - return defaultMode; + return defaultMode; } } @@ -119,8 +121,8 @@ static PorterDuffColorFilter updateTintFilter(Drawable drawable, PorterDuffColor return new PorterDuffColorFilter(color, tintMode); } - tryInvoke(tintFilter, "setColor", sCachedArgsTypes[0], color); - tryInvoke(tintFilter, "setMode", sCachedArgsTypes[1],tintMode); + tryInvoke(tintFilter, "setColor", INT_ARG, color); + tryInvoke(tintFilter, "setMode", MODE_ARG, tintMode); return tintFilter; }