I have an empty project (no classes whatsoever, no activities), only a dependency to com.google.android.material:material:1.3.0 for the code to compile (there is a style defined which uses this).
I enabled shrinking option, yet, after generating the signes APK, there is a classes.dex file in the apk with a shitload of code, even though the app has no code. Why and how to I get rid of those, to make sure the apk contains only what is needed, no extra bloatware? Thank you.
This is the expanded apk:
For code shrinking please turn on Proguard and you have the option to customized Proguard rules as you need.
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
}
}
TRY 1
Open .jar file (appodeal.jar) and remove all .dex files.
TRY 2
Use the built-in inspection Java | Declaration redundancy | Unused declaration.
To run it on whole project go to Analyze -> Run inspection by name..., type Unused declaration and select desired scope. Then carefully check output and mark some classes as entry points if needed.
Select Unused declaration node in list and perform Safe delete action on all unused declarations at once.
Related
I want to optimize my app size.For that,I want to analyze my app with android studio analyze apk tool.But it only show the file size not details report.
Please see https://medium.com/#arungiri.10/managing-application-size-50810d03b16c for detailed info.
Use below lines to enable app shrinking using R8.
buildTypes {
...
release {
...
useProguard false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
...
}
}
where proguard-rules.pro must be written by you based on your app. Generally this file contains lines of code to not obfuscate data / model classes.
Once you do this, a APK will be generated in the output/release directory. Use that APK in APK analyzer tool.
As we can see the data present inside a APK below.
If you click on classes.dex, it would show the classes present inside this dex file.
As you can see, the code is proguarded, you will also get option to add respective mapping.txt file which would help in reverse engineering and see the APK package data.
mapping.txt file is auto-generated and is present under outputs/mapping/release/. Use this to reverse engineer and see the actual class names.
Also, to add proguard rules for data classes, it's easy. Just select the class or package you want to keep from proguarding, right click on it and select "Generate Proguard Keep rule" as shown below.
Proguard rules will be auto generated, copy this and put it in above proguard-rules.pro file.
Hope this answer helps.
When prepare to release the Android app, we would use Proguard to obfuscate the code which may break the app.
So once some error occurs, we modify that and build-release-test again and again, is there a simple way to do that?
Also, is it possible to see the obfuscated code directly in Android Stuido?
Retracing
Retracing is what makes the obfuscated stack trace human-readable by replacing obfuscated names to the ones used in original source. In order to be able to retrace, make sure to save mapping.txt for every build you are about to test or send to someone. Mapping is unique for every build process.
Mapping can be found in
appModule/build/outputs/mapping/release/mapping.txt
For retracing, there is a convenient tool named proguardgui, found in
$ANDROID_HOME/tools/proguard/bin/proguardgui.sh
(*.sh for UNIX systems, for other platforms expect different extension).
Choose "ReTrace", add a mapping.txt (make sure to use mapping.txt that was generated for that apk build) and paste the obfuscated stack trace into window. Press "ReTrace" on bottom right corner and you should get that stack trace with deobfuscated names.
Here's a screenshot with sample input I found on the Internet
Decompiling
Also, is it possible to see the obfuscated code directly in Android Stuido?
No, but you might see the code by converting dex to jar and decompiling it.
dex2jar myapp.apk
jd-gui myapp-dex2jar.jar
dex2jar github page.
jd-gui from github page.
Practices I use to follow
What works for me is whenever I add a library I add a proguard config for a library (usually provided by library developer).
There's also a project called android-proguard-snippets, thought they are mostly outdated, so make sure to check from library developer first.
For easy management, I use to split the proguard config for every library in a separate file. Below is a snippet from one of my build.gradle buildTypes for release
proguardFile getDefaultProguardFile('proguard-android.txt')
proguardFile 'proguard-dart.pro'
proguardFile 'proguard-parceler.pro'
proguardFile 'proguard-retrolambda.pro'
proguardFile 'proguard-rules.pro'
proguardFile 'proguard-rx-java.pro'
proguardFile 'proguard-support-design.pro'
proguardFile 'proguard-support-v7-appcompat.pro'
For objects used in Firebase serialization, add #Keep annotation.
For fields used by Gson, add #SerializedName annotations or use #Keep on an object.
Whenever I use reflection (or Animators, which are technically the same) I make sure to add proguard rule to keep the code accessed by reflection just after I write such code. In the end there will be probably nothing to fix.
in the build.gradle file i set the minifyEnabled to be true as shown in the code below. my question is how can i see the effect of this statement? or in other words, as i am trying to minify the code and obfuscating it,
where can i see the code minified and obfuscated where is the result of this statement.
build.gradle:
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
The probably easiest way to verify that shrinking and obfuscation has been applied to your project is to check for the existence of the mapping file.
When ProGuard is executed during the android build using gradle, the following files are generated automatically (located in build/outputs/mapping/<buildtype>/):
mapping.txt: contains the mapping from original class / class member names to obfuscated ones
seeds.txt: contains the seeds that were used during shrinking, i.e. the classes / class members specified in -keep rules
usage.txt: contains the removed classes during shrinking
With the presence and contents of these files you can verify that ProGuard was executed correctly.
You can check it in simple way, just extract your apk, decompile .dex files and look at decompile sources.
Obfuscated code should have changed classes, functions, variables names.
Here is insightful post about how to do it.
I would like to use some xml files as mockups to preview different states of a layout, but I don't want to include it in the apk because thes xml files are only dedicated to preview purposes. I would like to tell gradle which files/directories to ignore for resources.
It would also be useful to easily reduce apk size for low memory devices by using products flavors, in a similar way as this excellent article explains.
Maybe proguard could help?
If you are using the android studio you can add resources by build flavors your want example you can add string resource for debug build only and different string resource for main release build. You just right click add a xml resource choose a resource type and specify the source set.
if you add a layout for debug flavor only and not in main release then everytime you sign an apk the those layout will not be included in apk. Hope it helps :)
We call it "Resource shrinking". All info about it is here.
Look at shrinkResources true. Build system will try to find unused resources files with this flag, and will remove them from the build. You can add it to your debug buildType, and on any build flavor.
android {
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
ProGuard is not doing a very complete job of obfuscating my Android project. When I decompile my apk at decompileandroid.com I see that it is only changing the name of local temporary variables and nothing else. It is not changing class names, variable names, method names, or anything else.
After reading the manual all of the optional commands seem to be telling it NOT to do something so I am left to think it should obfuscate everything by default.
my build.gradle has the following...
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
Neither of those two files exist is the project. The project is as it was converted from Eclipse by Android Studio.
What am I missing. Do I need to create those two files and put some proguard parameters in them - if so what. I want maximum obfuscation.
Thanks,
Dean
Set minifyEnabled true in order to turn on code shrinking, and
then shrinkResources true to turn on resource shrinking.
Reference for the quote