proguard propertie not understood - android

I am having a hard time understanding what this is doing in proguard:
Does it avoid obfocusing all protected methods in all public classes?
-keep public class * {
public protected *;
}
Please explain or refer to some good explanation

These lines keep all public classes, and inside these public classes, all public and all protected fields and methods. This means that it keeps all public API of the input code, which is suitable for processing libraries.
See the ProGuard manual > Examples > A typical library.

Related

Why some package-private classes are not obfuscated by Proguard?

Working with an Android project in Android Studio 3.2, having enabled Proguard and some specific rules, I'm not able to figure out the following:
a specific package (and its subpackages) in a library module, used by client code, is preserved through the rule:
-keep public class com.mylib.mypackage.** {
public protected *;
}
Now, within this package there are also a number of package-private classes, which should not be picked by that rule. Some of those classes are effectively obfuscated, both in their own names and their member names, which is fine.
Instead there are some classes, implementing public interfaces, whose class names are not obfuscated, while I'd expect they should. For completeness, their member names, when not part of interface, are effectively obfuscated.
Example:
/* package */ class InternalComponent implements ExternalInterface {
// ExternalInterface is kept: Ok
// InternalComponent is kept: don't like, I'd like it renamed
#Override
public void ExternalMethod() {
// this is kept: Ok
}
public void InternalMethod() {
// this is renamed: Ok
}
}
I'd like to highlight that InternalComponent is created within some other (kept) class and only returned to client code through the ExternalInterface.
How can I also obfuscate their class names as well, if possible?
Edit #1
After #emandt answer on Proguard output files, I double checked and com.mylib.mypackage.InternalComponent is listed in seeds.txt, which according to this blog post lists all items matched by keep rules. So, for some reason, the rule above also picks package-private classes, which still seems wrong to me.
Edit #2
In the meantime, I ended up doing exactly the same approach proposed by #shizhen. For completeness, in order to extend the exclusion to any package named internal, I modified my proguard rule as:
-keep public class !com.mylib.mypackage.**.internal.*, com.mylib.mypackage.** {
public protected *;
}
(note the first part before the comma, prefixed by !)
I'll mark #shizhen answer, though I'd like to be curious as to why the original rule is also picking package-private components.
Are you working on an Android Library project? Probably YES.
In order to achieve your purpose, I am afraid that you need to re-organise your packages into something like below:
Public interfaces
com.my.package.apiforusers
Private/Internal implementations
com.my.package.apiforusers.internal
Then for your obfuscation rules, you can have it like below:
-keep public class com.my.package.apiforusers.** { public *; }
So that only the public classes/interfaces are kept and all those ones inside com.my.package.apiforusers.internal will be obfuscated.
Please note the double-asterisk at the end so that public classes/interface are also kept for the sub-packages.
In "/build/outputs/mapping/release/" folder there are few files ("usage.txt", "seeds.txt", etc..) that contain the REASONS of why and which classes/variables/methods/etc.. are not-processed/not-shrinked/ot-obfuscated via ProGuard utilities.

Proguard keep parameter names for interface and abstract class

I am trying to prevent proguard from obfuscating interface (or abstract class) methods parameters.
Lets say I have this interface in my lib :
package com.mypackage;
public interface MyLibListener {
void onSomething(boolean success, String message);
}
And this proguard file :
-keepparameternames
-keep interface com.mypackage.MyLibListener {
*;
}
Then I assemble release and I get :
package com.mypackage;
public interface MyLibListener {
void onSomething(boolean var1, String var2);
}
Same thing with abstract classes or using #Keep annotations. Obfuscation option keepparameternames seems to work only for regular classes. Any idea? Thanks!
(related SO : How to not obfuscate interface methods & it's parameters using Progaurd in android? and Proguard keep interface method variable names)
Add following ProGuard options to your configuration.
-keepattributes MethodParameters
If your class file hava method parameters metadata (compiled using Java8 -parameters or etc...)`, ProGuard will keep the metadata.
To keep all interface methods:
-keep interface * {
<methods>;
}
To keep all public and protected methods, which could be used by reflection:
-keepclassmembernames class * {
public protected <methods>;
}
While I don't understand, why one would want to keep abstract classes, which cannot be instanced anyway, therefore it's pointless to keep & know their names. In theory, one could exclude all that is not abstract with rules which start with -keep !abstract, but that's kind of redundant.
Your proguard file may lack some -keepattributes, especially a -keepattributes Signature.
Check this example proguard configuration for a library from the proguard documentation to look for ideas.

How to get Proguard to `keepclassmembers` of entire package

As title says: How do I get Proguard to keepclassmembers of entire package? Also to net delete methods with void signatures.
To keep all class members (fields and methods) of all classes in a given package and all of its subpackages:
-keepclassmembers class mypackage.** { *; }
This includes void methods. To only keep all void methods:
-keepclassmembers class mypackage.** { void *(...); }
These are unusual settings though, because keeping all class members or all void methods (without even keeping all classes) seems like a very random requirement.
For most configurations, -keep is more appropriate than -keepclassmembers, relevant classes are typically only public ones (matching public class), relevant classes typically extend a specific class or interface (e.g. matching extends somepackage.SomeClass), and relevant class members are typically a very specific set of public methods (e.g. public setters, matching public void set*(***)).

crash using ORMLite on Android with proguard

We're using ORMLite in our Android app. It's working fine, except when we try to do a build with proguard switched on.
I've read various similar posts, and so far I've got in my proguard-project.txt
-keep class com.j256.** {
*;
}
as suggested in the following discussion http://sourceforge.net/p/proguard/discussion/182456/thread/6765bb69
and I've got
-keepclassmembers class * {
public <init>(android.content.Context);
public <init>(android.app.Activity,int);
}
as suggested in another stackoverflow question Proguard with OrmLite on Android
But it still not working. I can get it to run if I add
-dontobfuscate
but that somewhat missing the point of using proguard in the first place.
When I run I get an
IllegalStateException: Could not find OpenHelperClass because none of the generic
parameters of class class <our.package.name>.LaunchActivity extends
OrmLiteSqliteOpenHelper. You should use getHelper(Context, Class) instead.
Where
public class LaunchActivity extends OrmLiteBaseActivity<DatabaseHelper>
and
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
I've added
-keep public class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keep public class <our.package.name>.LaunchActivity
But still no luck. This question seems to have been asked before (Problems with OrmLite and proguard obfuscation) but I'm hoping somebody will know what the solution is!
The error message mentions generic parameters, so ORMLite is probably using reflection to retrieve generic type information. This information is stored in optional Signature attributes (Java erases generic types), which ProGuard removes by default. You can keep them with
-keepattributes Signature

android onClick events and pro guard

i'm trying to obfuscate my app before uploading to the market.
i've setup pro guard and i allready handled the Serialzie issue (prog guard maul - serialize) however i still have a problem (MethodNotFoundException) when trying to press one of the buttons in my home screen.
they are simple LinearLayout with background that in the xml have the android:onClick="doOnClick" attribute. in my HomeScreenActivity i have a method named :
public void doOnClick(View v){...}
that should be called whenever a button is pressed.
the code works GREAT when not obfuscated, but once obfuscated android class loader in unable to find my method. Before i move in to use only code and not xml callbacks (maybe advisable) i would like to know if there is a nice way around it.
Trying to prevent method obfuscation did not work for me (trying to prevent obfuscation of methods that extends Activity and are of the form public void on(android.view.View); or public void On(android.view.View).
If anyone have done it i'll appreciate the hint :-)
It's really simple, this should work.
-keepclasseswithmembers class MyActivity {
public void doOnClick(android.view.View);
}
Add this to your proguards file.
-keep class com.android.toto.ClassName {
public void doOnClick(android.view.View);
}
the -keep or keepclasswithmemebers do not apply since i already have -keep public class * extends android.app.Activity which will include ALL Activities.
I managed to find the problem in which the methods had been totally removed by proguard optimization and replaced with direct inline code. This happens because there are no specific calls to those functions in code; note that the XML calls to the code aren't taken into account.
adding the following to the proguard configuration solves the problem:
-keepclassmembers class * extends android.app.Activity {
public void *On*Click(android.view.View);
public void *on*Click(android.view.View);
}

Categories

Resources