Android app crashes in Release but not in Debug NullPointerException - android

I recently changed 2 lines of code as a workaround due to changes to the data being returned from an API I'm using. Now the app is crashing when using the release apk and aab. However, when I'm using the app through the Android Emulator on API 27 and connecting an API 27 device to my computer running the debug apk, the app works flawlessly.
I'm really stumped on this problem, and do not understand the error messages at all.
FATAL EXCEPTION: main
Process: com.guy.aqi, PID: 8328
java.lang.NullPointerException: throw with null exception
at com.guy.aqi.n.a(Unknown Source:3)
at com.guy.aqi.m.b(CurrentAirQualityFragment.java:8)
at com.guy.aqi.m.b(CurrentAirQualityFragment.java:6)
at com.guy.aqi.d.a(Unknown Source:4)
at b.a.a.a.m.c(StringRequest.java:4)
at b.a.a.a.m.a(StringRequest.java:1)
at b.a.a.h$a.run(ExecutorDelivery.java:4)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
My API stopped sending the "main pollutant" String, so I changed this line:
textViewMainPollutantUS.setText("U.S. Main Pollutant: " decodePollutant(mainPollutantUS));
to
textViewMainPollutantUS.setText("");
and this line:
textViewMainPollutantCN.setText("China Main Pollutant: " decodePollutant(mainPollutantCN));
to
textViewMainPollutantCN.setText("");
I expected changing these lines would fix the issue. But now the issue seems to be fixed in debug version of the app, but not the release version.
proguard-rules.pro
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform
# Prevent Proguard from inlining methods that are intentionally extracted to ensure locals have a
# constrained liveness scope by the GC. This is needed to avoid keeping previous request references
# alive for an indeterminate amount of time. See also https://github.com/google/volley/issues/114
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.NetworkDispatcher {
void processRequest();
}
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.CacheDispatcher {
void processRequest();
}
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
##---------------End: proguard configuration for Gson ----------
-keep class com.crashlytics.** { *; }
-keepattributes SourceFile,LineNumberTable

For me, adding lines (you may have other name for package where you put your POJO files):
-keep class [mypackagename].model.** { *; }
-keep class [mypackagename].datamodel.** { *; }
to proguard.rules worked perfectly, then options:
android
{
...
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
}
are set in build.gradle (Module: app)

Edit:-
Replace this
minifyEnabled true
to
minifyEnabled false

Related

Android crash with minifyEnabled and AWS call

Using variety of aws-android-sdk's (version 2.22.0) (including DynamoDB).
With minifyEnabled = true, Android app crashes in DynamoDB call. App does not crash if I disable that flag.
Here are the proguard-rules I'm using:
In build.gradle (app):
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
And in the proguard-rules.pro I have the following:
# Class names are needed in reflection
-keepnames class com.amazonaws.**
-keepnames class com.amazon.**
# Enums are not obfuscated correctly in combination with Gson
-keepclassmembers enum * { *; }
# Request handlers defined in request.handlers
-keep class com.amazonaws.services.**.*Handler
# The following are referenced but aren't required to run
-dontwarn com.fasterxml.jackson.**
# Android 6.0 release removes support for the Apache HTTP client
-dontwarn org.apache.http.**
# The SDK has several references of Apache HTTP client
-dontwarn com.amazonaws.http.**
-dontwarn com.amazonaws.metrics.**
Here's the pertinent call stack:
E/AndroidRuntime: FATAL EXCEPTION: Thread-13
Process: com.icefield.eventtruly, PID: 20298
java.lang.IllegalArgumentException: Illegal query expression: No hash key condition is found in the query
at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.processKeyConditions(:2711)
at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.createQueryRequestFromExpression(:2671)
at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.query(:2438)
at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.query(:2399)
at c.f.a.g.d$b.run(:339)
at java.lang.Thread.run(Thread.java:919)
Setting minifyEnabled = false results in everything working hunky-dory.
Any ideas on what else I might add to proguard rules?
I recommend using the following ProGuard rules.
-keep class com.amazon.** { *; }
-keep class com.amazonaws.** { *; }
-keep class com.amplifyframework.** { *; }
I suspect that you'll find a
ClassNotFoundException or and/or NoClassDefFoundError elsewhere in your logs, which will be more helpful to fine-tune the rules.
The particular error you're seeing arises when there are no key Conditions included in the request being sent to DyanmoDB.

Android R8 not obfuscating class names

I have been researching this for the past few hours without any luck. Class names are not obfuscated no matter what. These are just regular classes, not Activities, Services, or something else which is also in Android Manifest (I know those don't get obfuscated). What am I missing here?
Android Gradle Plugin version: 4.0.0
Gradle version: 6.1.1
Android Studio version: 4.0
With these versions, R8 should be enabled by default. Here is my buildType config:
buildTypes {
release {
//useProguard false // even tried this without luck
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
Here is my proguard-rules.pro
-ignorewarnings
# --- Glide ---
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# --- Billing library ---
-keep class com.android.vending.billing.**
# --- Retrofit2 ---
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
#retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { #retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
# --- TwitterKit ---
#Picasso Proguard Config https://github.com/square/picasso
-dontwarn com.squareup.okhttp.**
# --- GSON ---
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
#com.google.gson.annotations.SerializedName <fields>;
}
# --- SciChart ---
# ignore warnings and save classes required for syntax highlighting
-dontwarn java.awt.**
-dontwarn javax.swing.**
-dontwarn syntaxhighlight.**
-keep public class java.awt.** { *; }
-keep public class javax.swing.** { *; }
-keep public class syntaxhighlight.** { *; }
-keep public class prettify.** { *; }
# need to keep these classes and their methods because they are used by resampling code
-keep public class com.scichart.core.model.DoubleValues { *; }
-keep public class com.scichart.core.model.FloatValues { *; }
-keep public class com.scichart.core.model.IntegerValues { *; }
-keep public class com.scichart.data.model.Point2DSeries { *; }
# repack obfuscated classes into single package so it would be hard to find their originall package
-repackageclasses ''
-allowaccessmodification
Similar questions which I checked but didn't offer any solutions to this:
Android studio 3.4.2 R8 obfuscator does not obfuscate class names, but only java code inside
Class no longer obfuscated after upgrading to Android Gradle plugin 3.4.0
Android/java: Transition / Migration from ProGuard to R8?
As per WorkManager's proguard file, it is expected that all classes that extend ListenableWorker (and its subclasses, such as Worker) are kept. This is because the name of the class is the unique key in WorkManager's internal database.

Retrofit2 not working when enabling Proguard

I have an application which uses retrofit to fetch logo form an API.
When i don't obfuscate and shrink my code, everything works fine. But when i enable it, the API call stops working. I don't get any crash or error messages, i just don't get any values from the API.
gradle
buildTypes {
debug{
// Enables code shrinking, obfuscation, and optimization for only
// your project's release build type.
minifyEnabled true
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
release {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
I used it in debug just for testing purposes. If i use it in release, it has same output.
I checked the retrofit page and they advised to use the following file
proguard-rules.pro
# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile
-printusage usage.txt
-keep class com.th3pl4gu3.locky_offline.core.main.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.network.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.database.** {*;}
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
#retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { #retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
The API call still doesn't work. I tried many posts on stackoverflow but nothing works for me. Can someone help me by proposing a solution or an alternative to this ?
Thank you
Have you tried to put #SerializedName to Object field?
public class YourJsonClass{
#SerializedName("username")
String username;
}
Use progaurd rules from the official retrofit site
https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro
Sometimes issue seems to be from retrofit but it is not. It’s a GSON and ProGuard problem. To fix it you just have to add a -keep class configuration in your proguard rules of the package where your Pojo class is stored For example my API response and request classes are stored like this (package name may differ according to your app):
-keep class com.sample.myapp.model.request. { ; }
-keep class com.sample.myapp.model.model.response.* { ; }*

In Android Retrofit2 SimpleXml converter not working with minifyEnabled=true

I'm using following dependencies of retofit2 for xml and gson parsing.
compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
All is working fine and data parsing is correctly in debug and released apk. But when I release apk by using minifyEnabled=true and shrinkResources=true ,then xml parsing is not working any more. Gson was also causing problem and was resolved by applying SerializedName annotation to each attribute of Model because proguard renames attributes while generating apk which causes parsing issue.
How can i resolve the xml parsing issue as well? I want to use minifyEnabled necessarily.
Following commands are from Progurad Rules File.
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-dontwarn org.codehaus.mojo.animal_sniffer.**
-dontwarn java.nio.file.**
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# 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
-dontwarn javax.xml.stream.**
# SimpleXMLParsing
-keep public class org.simpleframework.** { *; }
-keep class org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.core.** { *; }
-keep class org.simpleframework.xml.util.** { *; }
-keepattributes ElementList, Root
-keepclassmembers class * {
#org.simpleframework.xml.* *;
}
-dontwarn jp.co.cyberagent.android.gpuimage.**

Proguard dontwarn and dontnote not taking effect

I am building an Android project that has some buildTypes that are using Proguard. During the build I am seeing a ton of warnings from Proguard. Because these warnings are generated for third party classes that I am using I'm attempting to use the -dontwarn flag and -dontnote flag in my 'proguard-rules.pro' file so that I won't see the error output in the future. However, the issue I'm seeing is that even after I add these flags to my .pro file and specify the .pro file in the build.gradle I'm still seeing the warnings output when the project is built.
Here is the relevant part of the build.gradle file:
buildTypes {
debug {
applicationIdSuffix ".debug"
}
unitTest {
applicationIdSuffix ".unittest"
minifyEnabled true
// proguardFiles getDefaultProguardFile("proguard-android.txt")
proguardFile('proguard-rules.pro')
}
automation {
applicationIdSuffix ".automation"
minifyEnabled true
// proguardFile getDefaultProguardFile('proguard-android.txt')
proguardFile('proguard-rules.pro')
}
internal {
applicationIdSuffix ".internal"
minifyEnabled true
// proguardFiles getDefaultProguardFile('proguard-android.txt')
proguardFile('proguard-rules.pro')
}
release {
minifyEnabled true
// proguardFiles getDefaultProguardFile("proguard-android.txt")
proguardFile("proguard-rules.pro")
}
}
Here's my proguard-rules.pro file:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Disabling obfuscation is useful if you collect stack traces from production crashes
# (unless you are using a system that supports de-obfuscate the stack traces).
-dontobfuscate
# React Native
# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation #interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation #interface com.facebook.proguard.annotations.KeepGettersAndSetters
# Do not strip any method/class that is annotated with #DoNotStrip
-keep #com.facebook.proguard.annotations.DoNotStrip class *
-keepclassmembers class * {
#com.facebook.proguard.annotations.DoNotStrip *;
}
-keepclassmembers #com.facebook.proguard.annotations.KeepGettersAndSetters class * {
void set*(***);
*** get*();
}
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
-keepclassmembers class * { #com.facebook.react.uimanager.UIProp <fields>; }
-keepclassmembers class * { #com.facebook.react.uimanager.annotations.ReactProp <methods>; }
-keepclassmembers class * { #com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
-dontwarn com.facebook.react.**
# okhttp
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
# okio
-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
# stetho
-dontwarn com.facebook.stetho.**
##ADDED TO GET WARNINGS TO GO AWAY BUT NEEDS TO BE EVALED BEFORE RELEASE
-dontnote junit.runner.*
-dontnote junit.framework.*
-dontwarn org.hamcrest.**
-dontwarn android.support.test.**
Note the proguard-rules.pro file is located in my project/app/ directory next to the build.gradle file that references it.
Here's a snippet of the error output from gradle:
Note: duplicate definition of library class [junit.runner.Version]
Note: duplicate definition of library class [junit.runner.BaseTestRunner]
Note: duplicate definition of library class [junit.framework.Protectable]
Note: duplicate definition of library class [junit.framework.Assert]
Note: duplicate definition of library class [junit.framework.TestSuite]
Note: duplicate definition of library class [junit.framework.Test]
Note: duplicate definition of library class [junit.framework.ComparisonFailure]
Note: duplicate definition of library class [junit.framework.TestFailure]
Note: duplicate definition of library class [junit.framework.TestCase]
Note: duplicate definition of library class [junit.framework.AssertionFailedError]
Note: duplicate definition of library class [junit.framework.TestListener]
Note: duplicate definition of library class [junit.framework.TestResult]
Reading library jar [/Users/dhodapp/Library/Android/sdk/platforms/android-23/optional/org.apache.http.legacy.jar]
Note: duplicate definition of library class [android.net.http.SslCertificate]
Note: duplicate definition of library class [android.net.http.SslError]
Note: duplicate definition of library class [android.net.http.SslCertificate$DName]
Note: duplicate definition of library class [org.apache.http.conn.scheme.SocketFactory]
Note: duplicate definition of library class [org.apache.http.conn.scheme.HostNameResolver]
Note: duplicate definition of library class [org.apache.http.conn.ConnectTimeoutException]
Note: duplicate definition of library class [org.apache.http.params.HttpParams]
Note: there were 19 duplicate class definitions.
(http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)
Warning: org.hamcrest.integration.EasyMock2Adapter: can't find superclass or interface org.easymock.IArgumentMatcher
Warning: org.hamcrest.integration.JMock1Adapter: can't find superclass or interface org.jmock.core.Constraint
Warning: library class android.test.AndroidTestCase extends or implements program class junit.framework.TestCase
Warning: library class android.test.AndroidTestRunner extends or implements program class junit.runner.BaseTestRunner
Warning: library class android.test.InstrumentationTestCase extends or implements program class junit.framework.TestCase
Warning: library class android.test.InstrumentationTestSuite extends or implements program class junit.framework.TestSuite
Why aren't the error messages being squashed when I apply the proguard-rules.pro file?

Categories

Resources