【发布时间】:2019-06-29 23:52:45
【问题描述】:
我最近更改了 2 行代码作为解决方法,因为我正在使用的 API 返回的数据发生更改。现在应用程序在使用发布 apk 和 aab 时崩溃。但是,当我通过 API 27 上的 Android Emulator 使用该应用程序并将 API 27 设备连接到运行调试 apk 的计算机时,该应用程序可以完美运行。
我真的被这个问题难住了,根本不理解错误信息。
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)
我的 API 停止发送“主要污染物”字符串,所以我更改了这一行:
textViewMainPollutantUS.setText("U.S. Main Pollutant: " decodePollutant(mainPollutantUS));
到
textViewMainPollutantUS.setText("");
还有这一行:
textViewMainPollutantCN.setText("China Main Pollutant: " decodePollutant(mainPollutantCN));
到
textViewMainPollutantCN.setText("");
我预计更改这些行会解决问题。但是现在这个问题似乎在应用程序的调试版本中得到了修复,而不是发布版本。
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
【问题讨论】:
-
这里发布的代码很难确定。关于发布的代码来自哪个类的一些上下文会有所帮助。处理这里的内容,
textViewMainPollutantCN可能为空。或者CurrentAirQualityFragment中的某个其他对象为空。尝试暂时禁用 proguard 以获得更多有用的类名和崩溃发生位置的信息。 -
@marJavaCode 我在关闭 proguard 的情况下重建了应用程序(minifyEnable false,shrinkResources false),并且发布版本可以正常工作而不会崩溃。但是,当使用带有 proguard 的应用程序(minifyEnable true,shrinkResources true)时,它会在启动时崩溃。也许它与我的proguard规则有关?我已经更新了我的问题以包含 proguard 规则文件。
-
在不知道 NPE 发生在哪里的情况下,很难判断是什么导致了这个问题(所有输出都表明可以追溯到
CurrentAirQualityFragment中的某些内容)。 暂时将-keepnames class **添加到proguard 规则可以帮助调试(这将禁用混淆)。只要确保不要把它留在那里。正确的类名可以帮助将问题追踪到某一行。您还可以查看CurrentAirQualityFragment的第 8 行,以帮助找出未知类可能是什么。 -
CurrentAirQualityFragment的第 8 行只是import android.graphics.Color;的导入语句。我添加了 proguard 规则,Logcat 指向第 248 行:cityName.setText(station.getData().getCity());这在调试模式下工作正常,并且站对象不应为空。 -
getData()返回的任何内容都可能为空。尝试添加Log.i("DataValue", "Is null: " + station.getData() == null);如果日志行导致 NPE,则站必须为空。如果它打印“Is null: true”,则数据为空。任何为 null 的内容都可能无法初始化,而另一个-keep class规则将解决该问题,但在不知道它为 null 并查看其初始化的情况下,很难说出需要保留的内容。
标签: android nullpointerexception crash