I have a proguard.cfg file which contains several statements including optimization passes and logs suppression as :
-assumenosideeffects class android.util.Log { *; }
-assumenosideeffects class com.badlogic.gdx.Application {
public static void debug(...);
public static void error(...);
public static void log(...);
}
Calls to Log.* are correctly removed in the final output APK file. But gdx log calls are still in the code. For example I can still see things like that in the output :
Gdx.app.debug("debug()", "^");
Gdx.app.error("error()", "^");
Gdx.app.log("log()", "^");
I also tried to put this part of my config in a proguard-optimize.txt file as I have seen on similar questions and then setting the proper value in project.properties files like this : proguard.config=proguard-optimize.txt:proguard.txt but it doesn't work !
These calls get removed only if I put a general wildcard :
-assumenosideeffects class com.badlogic.gdx.Application {
*;
}
But I don't want to remove calls to other Application's static methods, like add* and get*() ones.
Optimization step is enabled (6 passes).
Gdx.app.debug is not static its an instance method (app is a static field of the Gdx class).
Try:
-assumenosideeffects class com.badlogic.gdx.Application {
public void debug(...);
public void error(...);
public void log(...);
}
Try something like this in your application's code:
Gdx.app.setLogLevel(Application.LOG_NONE);
That will prevent messages from being logged.
Cheers!
Related
I had a strange bug which was hard to find :-(
In my Android app I use Retrofit2 with Moshi do access an api. I also use proguard-android-optimize.txt to make my app clean and small. And in my proguard-rules.pro I have:
-assumenosideeffects class timber.log.Timber { *; }
-assumenosideeffects class android.util.Log { *; }
With this combination I get this error stream was reset: null when I try to access the api.
To fix it I have to remove this assumenosideeffects lines from my proguard config. But why? Has anyone an idea why I get this network problem when proguard removes logging methods?
The wildcard * matches all methods, including methods in super classes, like Object#wait(). You don't really want to remove those invocations, so you should explicitly list the methods for which you want to remove the invocations:
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
ProGuard already prints out a warning if you specify the wildcard.
Following Removing unused strings during ProGuard optimisation I created Logg class that is designed to be easily removed by Proguard:
public class Logg {
public static void e(Object... args) {
Log.e(TAG, buildString(args));
}
public static void d(Object... args) {
Log.d(TAG, buildString(args));
}
}
Next, I added these rules to proguard-rules.pro used by project:
-assumenosideeffects class com.mypackage.Logg {
public static *** d(...);
public static *** e(...);
}
-optimizationpasses 10
After the project is built, I inspect the resulting classes.jar file with JD-GUI and see lines like these:
new Object[1][0] = "Some log message";
The Logg.e(... call is removed but the constant is still there. With -optimizationpasses 5 the line was mentioning String instead of Object.
Is there a way to make sure that Proguard will remove those Strings?
i am using Dexguard in my android application to protect from
reverse engineering.Now in my application which is very big ,i have
used several places System.out.println in many classes in which i am
printing my server URL to debugg for my ease.Now when i am releasing
this application ,and this apk i am giving to other developers ,they
can see all the System.out.println things in their logcat. how
should i avoid that. This has serious issue.
First of all you shouldn't be using System.out.println directly everywhere. Use your own wrapper class for logging.
In dexguard/proguard you can use assumenosideeffects for removing codes that are unnecessary for release.
So for System.out.print you can add following in your dexguard rules.
-assumenosideeffects class java.io.PrintStream {
public void println(%);
public void println(**);
}
But this is risky as this class might be used for purposes other than logging.
Fastest way for you would be to use android.util.Log in place of System.out.print and then add following
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
See proguard docs
good answer by #vKashyap, you might also want to add this as well...
-assumenosideeffects class java.lang.Exception {
public void printStackTrace();
}
I'm trying to export a signed app and when I run my app i get this exception
Could not dispatch event: class com.achlan.myapp.events.e to subscribing class class com.achlan.myapp.b.d
mapping.txt:
com.achlan.myapp.events.RestResult -> com.achlan.myapp.events.e
com.achlan.myapp.data.DataManager -> com.achlan.myapp.b.d:
I've already added this line to my proguard config:
-keepclassmembers class ** {
public void onEvent*(**); }
Am I missing something in my proguard config?
I also had an issue with EventBus and ProGuard and I contacted the creator of ProGuard/DexGuard and he sent me the following 'workaround' which might help:
-keepclassmembers,includedescriptorclasses class ** { public void onEvent*(**); }
Add includedescriptorclasses to your config file to prevent ProGuard/DexGuard's optimization step to add a suffix to the method name.
Do not confuse the method. I do like this:
If I use
EventBus.getDefault().register(this, "getName", Name.class);
I will do
-keepclassmembers class ** {
public void getName(**);
}
It can work.
If you use a non public (package private) onEvent method you will need to update your progaurd config as follows:
-keepclassmembers class ** {
public void onEvent*(**);
void onEvent*(**);
}
Conside the following code structure for android:
package blah;
class A{
class B{
public void foo(String s){
}
}
}
How can I tell proguard to not remove or obfuscate foo.
foo is unused function in code at compile time but is run at run-time from another code.
I have tried:
-keep class blah.A.B;
-keepclassmembers class blah.A.B {
public void foo(String s);
}
etc. but nothing stops Proguard from removing that function.
I do not want proguard to change name of 'foo'. Proguard may change the name of class A or class B but not the function name 'foo'.
Any suggestions?
Almost right. In java bytecode, the $ character separates the names of inner classes and their outer classes (to avoid ambiguities with package names). So, to keep just the method:
-keepclassmembers class blah.A$B {
public void foo(java.lang.String);
}
I have a method 'myClickHandler' referenced only in an xml file.
This
-keepclassmembers class * extends android.app.Activity {
public void myClickHandler(android.view.View );
}
stops it being removed in my application. Perhaps the extends .. will work for you