I have just used proguard, but classes I am trying to instantiate via reflection are not working.
I have an interface
Algorithm
I pass classes like this
AlgorithmFactory.SomeClassThatExtendsAlgorithmImpl.class
The class is instantiated like this
public ArrayList<Algorithm> getAlgorithms(Context cnx) { ArrayList<Algorithm> list = new ArrayList<Algorithm>(); for(Class<? extends Algorithm> alg: algorithms) { try { Constructor<? extends Algorithm> c = alg.getConstructor(Context.class); list.add(c.newInstance(cnx)); } catch (IllegalArgumentException e) { Log.e(TAG, "IllegalArgumentException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (InvocationTargetException e) { Log.e(TAG, "InvocationTargetException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (InstantiationException e) { Log.e(TAG, "InstantiationException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (IllegalAccessException e) { Log.e(TAG, "IllegalAccessException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (SecurityException e) { Log.e(TAG, "SecurityException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } catch (NoSuchMethodException e) { Log.e(TAG, "NoSuchMethodException", e); throw new IllegalStateException("There was a problem creating the Algorithm class"); } } return list; }
Here is my proguard.cnf
-optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class com.android.vending.licensing.ILicensingService -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembernames class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -assumenosideeffects class android.util.Log { public static *** d(...); public static *** v(...); public static *** i(...); public static *** w(...); public static *** e(...); }
ProGuard is a tool to help minify, obfuscate, and optimize your code. It is not only especially useful for reducing the overall size of your Android application as well as removing unused classes and methods that contribute towards the intrinsic 64k method limit of Android applications.
Reflection allows programmatic access to information about the fields, methods and constructors of loaded classes, and the use of reflected fields, methods, and constructors to operate on their underlying counterparts, within encapsulation and security restrictions.
Android supports reflection. Once you've got a prototype running, you can benchmark and determine your bottlenecks. If its reflection, then consider trying to cache interfaces and such to make it a one-off cost, rather than continually resolving the same interfaces from the same instances repeatedly.
R8 has more Kotlin support than that of Proguard. R8 is having a faster processing time than Proguard which reduces build time. R8 gives better output results than Proguard. R8 reduces the app size by 10 % whereas Proguard reduces app size by 8.5 %.
For others that are having this problem you need to add the following to proguard.cnf
-keep public class * extends com.yoursite.android.yourappname.YourClassName -keepclassmembers class * extends com.yoursite.android.yourappname.YourClassName{ public <init>(android.content.Context); }
The first keep tells proguard to not obfuscate class names that extend YourClassName
The second one says to keep the constructor name (<init>
means constructor) un-obfuscated that has a single argument of Context
and extends YourClassName
In addition, for android developers that are using the onClick attribute in you XML layouts file you will also need to add the name of the function in your proguard.cnf file.
-keepclassmembers class * { public void myClickHandler(android.view.View); }
This says keep all methods named myClickHandler
with a single argument View
in all classes. You could further constrain this by using the extends keyword like above.
hope this helps.
For the on click fix you don't have to list each method name. You can do:
-keepclassmembers class * { public void *(android.view.View); }
which find all methods that have a View as parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With