@@ -112,11 +112,19 @@ static String resolveMethodOverload(Class<?> clazz, String methodName, Object[]
112112 methodOverloadsForClass .put (c , finder );
113113 }
114114
115- ArrayList <Method > matchingMethods = finder .getMatchingMethods (methodName );
116- tryFindMatches (methodName , candidates , args , argLength , matchingMethods );
117- if (candidates .size () > iterationIndex && candidates .get (iterationIndex ).y == 0 ) {
118- // direct matching (distance 0) found
119- break ;
115+ if (!finder .errorGettingMethods ()) {
116+ ArrayList <Method > matchingMethods = finder .getMatchingMethods (methodName );
117+ tryFindMatches (methodName , candidates , args , argLength , matchingMethods );
118+ if (candidates .size () > iterationIndex && candidates .get (iterationIndex ).y == 0 ) {
119+ // direct matching (distance 0) found
120+ break ;
121+ }
122+ } else {
123+ Method method = finder .getMatchingMethodWithArguments (methodName , args );
124+ if (method != null ) {
125+ candidates .add (new Tuple <>(method , 0 ));
126+ break ;
127+ }
120128 }
121129
122130 c = c .getSuperclass ();
@@ -479,11 +487,42 @@ private static boolean convertPrimitiveArg(Class<?> primitiveType, Object[] args
479487 static class MethodFinder {
480488 private Method [] declaredMethods ;
481489 private HashMap <String , ArrayList <Method >> matchingMethods = new HashMap <String , ArrayList <Method >>();
490+ private final Class <?> clazz ;
491+ private final boolean couldNotGetMethods ;
492+
482493 public MethodFinder (Class <?> clazz ) {
483- this .declaredMethods = clazz .getDeclaredMethods ();
494+ this .clazz = clazz ;
495+ boolean errorGettingMethods = false ;
496+ try {
497+ this .declaredMethods = clazz .getDeclaredMethods ();
498+ } catch (NoClassDefFoundError error ) {
499+ // get at least the public methods as it shouldn't fail with NoClassDefFoundError
500+ // it is not a good practice to catch Errors in Java, but we have the following case:
501+ // when using support library > 26.0.0 and android API < 23
502+ // if we try to create android.support.design.widget.TextInputLayout and call its addView method
503+ // such error is thrown for android.view.ViewStructure as it is not present in older APIs
504+ // so in that case we are going to get only the public methods using getMethods which may or may not throw the same error
505+ // depends on the java Class implementation, on some of the cases it calls getDeclaredMethods() internally and
506+ try {
507+ this .declaredMethods = clazz .getMethods ();
508+ } catch (NoClassDefFoundError err ) {
509+ // if an error is thrown here we would set the declared methods to an empty array
510+ // then when searching for a method we will try to find the exact method instead of looking in the declaredMethods list
511+ this .declaredMethods = new Method []{};
512+ errorGettingMethods = true ;
513+ }
514+ }
515+ this .couldNotGetMethods = errorGettingMethods ;
516+ }
517+
518+ public boolean errorGettingMethods () {
519+ return couldNotGetMethods ;
484520 }
485521
486522 public ArrayList <Method > getMatchingMethods (String methodName ) {
523+ if (this .errorGettingMethods ()) {
524+ return null ;
525+ }
487526 ArrayList <Method > matches = this .matchingMethods .get (methodName );
488527 if (matches == null ) {
489528 matches = new ArrayList <Method >();
@@ -505,5 +544,19 @@ public ArrayList<Method> getMatchingMethods(String methodName) {
505544
506545 return matches ;
507546 }
547+
548+ public Method getMatchingMethodWithArguments (String methodName , Object [] args ) {
549+ // fallback mechanism to try to find the exact method by name and arguments
550+ // this method is not so useful as the arguments need to match the method types directly, but still it can find a method in some cases
551+ Class <?>[] types = new Class <?>[args .length ];
552+ for (int i = 0 ; i < args .length ; i ++) {
553+ types [i ] = args [i ].getClass ();
554+ }
555+ try {
556+ return this .clazz .getDeclaredMethod (methodName , types );
557+ } catch (NoSuchMethodException ex ) {
558+ return null ;
559+ }
560+ }
508561 }
509562}
0 commit comments