Signed APK crashes on Runtime while Unsigned APK doesn't (Proguard) - android

I've been facing this problem for weeks now and I still can't get it to work.
First of all I am using data binding for my project and it all runs smoothly without any runtime crashes using Android Studio's ADB. Even when I generated a signed "debug" APK for testing, it runs smoothly as well, until I set minifyEnabled to "true" on the debug and exported the APK (debug) out and it crashes.
So, I'm pretty sure there's something to do with Proguard optimising my classes / files.
Here is my app module :
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
So, to sum it up. When I change the debug's "minifyEnabled" to "false" and export the APK and test it on my phone, it runs fine.
But when I change it to "true", it crashes on runtime.
I've already added '-keep class' and '-dontwarn' in my proguard file.
Here it is :
-dontwarn android.databinding.**
-keep class android.databinding.** { *; }
-keep class android.databinding.annotationprocessor.** { *; }
-dontwarn android.viewmodel.**
-keep class android.viewmodel.** { *; }
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-dontwarn android.support.v7.**
-keep class android.support.v7.** { *; }
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
-keep class java.lang.** { *; }
My project runs Crashlytics and I've seen the error of the crash, which points to the databinding class. But I've already told proguard to keep the class as stated above.
I'm not sure what I'm missing here, this is the error I'm getting from Crashlytics :
com.myproject.android.databinding.ItemProductDataBinding.executeBindings (Unknown Source)
How do I know which class Proguard is helping to optimise and which class isn't? Hope you guys have the answer, and save me another few weeks of headaches. Thanks for reading.

Related

FCM doesn't work after enabling Proguard in gradle

I connected FCM and tested before. And it worked fine.
However, I am ready to publish my app and enabled proguard in build.gradle
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
proguardFile 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
proguardFile 'proguard-rules.pro'
// proguardFile 'proguard_debug.pro'
}
}
And applied this in proguard-rules.pro:
-keep class com.firebase.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class javax.servlet.** { *; }
-keepnames class org.ietf.jgss.** { *; }
-dontwarn org.w3c.dom.**
-dontwarn org.joda.time.**
-dontwarn org.shaded.apache.**
-dontwarn org.ietf.jgss.**
-dontwarn com.firebase.**
-dontnote com.firebase.client.core.GaePlatform
Everyone get push messages but just my test phone doesn't receive them which is proguard enabled. I converted my data models to Serialize format. But now this problem is happening.
How can I use FCM or other Firebase features such as Remote Config or Crashlystics?
Obfuscation renames variables in Kotlin data class without #SerializedName and as result Json not parsing to model class.
To prevent this you can use #Keep annotation
#Keep
data class MyClass(...)
or set #SerializedName to all values

How to enable proguard for only one module

I have a payment application with payumoney integration. It was working fine until i added the proguard. Recently I have added Proguard to my build.gradle file (Module: app)
` buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}`
After this App gets closed when i proceed to payment. It is working fine when i Changed minifyEnabled to false.
Following is my Module:PayuMoneySdk Build.gradle File
`buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}`
How can I solve this issue? I can't disable proguard.
Can I enable proguard to only Module:app? And will it solve the issue?
I am new to programming. Please help!!
The solution is to look up for the methods and classess that needs to be exempted and add them to the proguard rules as follows..
-keep class com.mm.** {*;}
-keep class com.company.** {*;}
-keepclassmembers class com.mm.** {*;}
-keepclassmembers class com.company.** {*;}
add below lines in proguard-rule.pro file
-dontwarn okio.**
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
-keep class com.** { *; }

Proguard not minifying when debuggable set to true

I am trying to test my app which has passed the 64K limit.
I have set minify on but it doesn't work when debuggable is enabled. However, if I build a version with debuggable off then it shrinks it by 2/3!
Am I missing something? This is the relevant part of my Gradle file:
buildTypes {
release {
minifyEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
proguard-rules.pro:
-keep class .R
-keep class **.R$* {
<fields>;
}
-keepattributes *Annotation*
-keepclassmembers class ** {
#org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
-dontwarn com.google.**
-dontwarn com.squareup.picasso.**
-dontnote com.google.**
-dontnote com.squareup.picasso.**
With proguard enabled your code gets obfuscated and debugging will not be possible. That is why when you want to debug and set the flag true, proguard does not activate and that is why you do not see the minification of your apk.
Check this post. It has a similar question and will help you understand the conditions better.

How to obfuscate UiAutomator code?

I have a test project developed in UiAutomator, which is not specific for one app, i.e., I don't even have any application associated to my test. My main folder only has the AndroidManifest, my code is all in the test folder.
I want to make my code available but ofuscated. So I want to obtain an APK of my code obfuscated.
My build.gradle contains
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles('proguard-rules.pro')
}
debug{
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFiles('proguard-rules.pro')
debuggable true
}
}
and proguard-rules.pro file is:
-keep public class * extends android.test.InstrumentationTestCase
-keep public class * extends junit.framework.TestCase
-keep public class * implements junit.framework.TestCase
-keep class android.support.** { *;}
-keep interface android.support.** { *;}
-keep public class junit.framework.** { *;}
-keep class android.uiautomator.** { *;}
-keep class com.impactToolTester.utility.Constants
-keepclasseswithmembernames class *{
public <init>(java.lang.Class,android.support.test.internal.util.AndroidRunnerParams);
}
-dontnote android.support.test.internal.runner.listener.CoverageListener
-dontwarn android.test.**
-dontnote org.junit.**
-dontnote junit.runner.*
-dontnote junit.framework.*
-dontnote android.net.**
-dontnote org.apache.http.**
When I run gradlew assembleAndroidTest the app-debug-androidTest-unaligned.apk is created in build/outputs/apk.
However, when I decompile the apk I realise it's not obfuscated at all. I know the proguard file is read because I started with several errors when I first run it.
I have the minifyEnabled in both debug and release because I'm not sure which is run with assembleAndroidTest.
I'm a real newbie when it comes to proguard and obfuscation in general so any help would be much appreciated.

How to use the ProGuard in Android Studio?

This is my first project in Android Studio, and the code of my apps are not obfuscated.
Im using this configuration in build.gradle file:
I'm using the Build > Generate Signed APK... with the Run Proguard checked.
And, when I have tested using the Apk_OneClick.v4.2, my code is completly easy to read:
Please, help-me. :(
You're probably not actually signing the release build of the APK via the signing wizard. You can either build the release APK from the command line with the command:
./gradlew assembleRelease
or you can choose the release variant from the Build Variants view and build it from the GUI:
You can configure your build.gradle file for proguard implementation. It can be at module level or the project level.
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
The configuration shown is for debug level but you can write you own build flavors like shown below inside buildTypes:
myproductionbuild{
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
Better to have your debug with minifyEnabled false and productionbuild and other builds as minifyEnabled true.
Copy your proguard-rules.txt file in the root of your module or project folder like
$YOUR_PROJECT_DIR\YoutProject\yourmodule\proguard-rules.txt
You can change the name of your file as you want. After configuration use one of the three options available to generate your build as per the buildType
Go to gradle task in right panel and search for assembleRelease/assemble(#your_defined_buildtype) under module tasks
Go to Build Variant in Left Panel and select the build from drop down
Go to project root directory in File Explorer and open cmd/terminal and run
Linux ./gradlew assembleRelease or assemble(#your_defined_buildtype)
Windows gradlew assembleRelease or assemble(#your_defined_buildtype)
You can find apk in your module/build directory.
More about the configuration and proguard files location is available at the link
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Running-ProGuard
NB.: Now instead of
runProguard false
you'll need to use
minifyEnabled false
Here is Some of Most Common Proguard Rules that you need to add in proguard-rules.pro file in Android Sutdio.
ButterKnife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
#butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
#butterknife.* <methods>;
}
Retrofit
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepattributes Signature
-keepattributes Exceptions
OkHttp3
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
Gson
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
Code obfuscation
-keepclassmembers class com.yourname.models** { <fields>; }
Try renaming your 'proguard-rules.txt' file to 'proguard-android.txt' and remove the reference to 'proguard-rules.txt' in your gradle file. The getDefaultProguardFile(...) call references a different default proguard file, one provided by Google and not that in your project. So remove this as well, so that here the gradle file reads:
buildTypes {
release {
runProguard true
proguardFile 'proguard-android.txt'
}
}
The other answers here are great references on using proguard. However, I haven't seen an issue discussed that I ran into that was a mind bender. After you generate a signed release .apk, it's put in the /release folder in your app but my app had an apk that wasn't in the /release folder. Hence, I spent hours decompiling the wrong apk wondering why my proguard changes were having no affect. Hope this helps someone!
Enable ProGuard
[ProGuard flow]
android {
buildTypes {
release {
minifyEnabled true
proguardFiles 'proguard-rules.pro'
}
}
}
[ProGuard artefact]

Categories

Resources