minifyEnabled导致应用在发布模式下崩溃

26
我的应用在调试模式下运行良好。但是,上传到Google Play Store后,我发现应用程序崩溃了。我查找了几个类似的问题,都建议禁用Proguard或检查日志输出。然而,在使用发布版构建变体时,我遇到了以下情况: 1- 在正常情况下,当minifyEnabledtrue时,应用程序会崩溃,我无法看到任何日志输出。没有可调试的进程。
release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }

2-debuggable true 设置为我的应用程序可以正常工作。但是由于应用程序正常工作,我仍然无法看到任何错误日志。

release {
            debuggable true
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }

3- 当注释掉minifyEnabled true时,应用程序可以工作。但我会失去代码缩小的好处。

release {
            shrinkResources true
            //minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.config
        }

我也尝试在AndroidManifest.XML中硬编码android:debuggable="true",但是会出错。

奇怪的是,将debuggable设置为true后,应用程序可以正常工作。我不确定在发布模式下是否应该保留debuggable true或禁用缩小,或者采取其他解决此问题的方法。

如果有人能分享如何解决这个问题,我将非常感激。

更新:通过运行Android Device Monitor,我找到了问题所在:

01-28 00:28:13.764: E/AndroidRuntime(4806): FATAL EXCEPTION: main
01-28 00:28:13.764: E/AndroidRuntime(4806): Process: com.example.myapp, PID: 4806
01-28 00:28:13.764: E/AndroidRuntime(4806): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.SearchView.setSearchableInfo(android.app.SearchableInfo)' on a null object reference
01-28 00:28:13.764: E/AndroidRuntime(4806):     at com.example.myapp.MainActivity.onCreateOptionsMenu(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.app.Activity.onCreatePanelMenu(Activity.java:3142)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v4.b.n.onCreatePanelMenu(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v7.view.i.onCreatePanelMenu(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v7.app.h$b.onCreatePanelMenu(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v7.view.i.onCreatePanelMenu(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v7.app.q.j(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.support.v7.app.q$1.run(Unknown Source)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.os.Handler.handleCallback(Handler.java:739)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.os.Handler.dispatchMessage(Handler.java:95)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.os.Looper.loop(Looper.java:148)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at android.app.ActivityThread.main(ActivityThread.java:7329)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at java.lang.reflect.Method.invoke(Native Method)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
01-28 00:28:13.764: E/AndroidRuntime(4806):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

如果应用程序崩溃,则需要配置ProGuard。具体配置取决于您的项目及其依赖关系。每个项目都将有不同的配置。 - Piotr Wittchen
1
四年过去了,这个问题仍然存在。收到来自各地的电话,称应用在发布模式下崩溃,显然是minifyenabled的问题。安卓是真的糟糕的操作系统,由Gooogle管理得很差。 - Karanveer Singh
@Darush,你能否详细说明一下你是如何发现avd问题的?我也遇到了同样的问题,在发布模式下没有日志,所以我不知道在proguard中应该保留什么。谢谢! - user2424380
将你的发布版本构建类型中的debuggable设置为true,以查看日志。 - Darush
1
@user2424380 我使用 Android 设备监视器成功捕获了错误。不幸的是,这个工具在最新版本中已被 Debugger 窗口取代。但是,如果您仍然无法看到崩溃日志,您可以使用崩溃报告工具或在 debuggable 为 true 的情况下彻底测试您的应用程序。 - Darush
显示剩余6条评论
3个回答

16

看起来Proguard无法正确处理SearchView小部件。我将以下行添加到proguard-rules.pro文件中,该文件位于app文件夹内,问题消失了:

-keep class android.support.v7.widget.SearchView { *; }

现在我不需要将minifyEnabled设置为false。

更新:

对于那些仍然无法在Android Studio中查看错误日志或在发布版本上重现崩溃的人,他们可以使用在线崩溃报告工具。


1
我遇到了一个类似的问题,修改“-keep class”值似乎无法解决。应用程序在模拟器中运行良好,但在我的手机上崩溃了。为了挤出更多的加载速度优化,他们让Android Studio变得非常不直观,这真是太遗憾了。 - Abandoned Cart
4
对我来说很不幸,minifyEnabled也导致了崩溃,而且老实说,如果没有人工排查并明确调用不进行代码混淆的异常,它就无法正常工作,那么这个功能就不值得麻烦。令人失望的是它不能直接开箱即用。 - spartygw
我也遇到了同样的问题,我的应用程序中没有任何SearchView,但它仍然崩溃!对此有什么建议吗! - Siddharth Thakkar
1
您可以在运行应用程序时,在终端中运行adb logcat,然后您就能够看到输出。 - Alejandra
在我的情况下,logcat选项是正确的选择。 - Pexers
我遇到了一个问题,是由于一个 Room 实体类引起的。在我的 RemoteKeyEntity 中,主键值是非空的,但在代码混淆后,它变成了空值,导致出现了 NPE(空指针异常)。使用 @Keep 注解或者 Proguard 规则都无法解决这个问题。 - undefined

3

我也遇到了同样的应用程序崩溃问题。在我的情况下,我正在从assets读取一个JSON文件,并使用Gson库将其转换为Kotlin data class。这些是类:

data class JournalData(
    val name: String,
    val url: String,
    val category: Categories
)

enum class Categories { POLITICS, SPORTS, TECHNOLOGY }

当使用minifyEnabled=true时,我遇到了两个问题:

  1. 随机名称混淆了数据类属性。例如,属性name被混淆为XYZ或其他随机名称。
  2. 分类枚举类常量也被混淆了,因此解析器无法将JSON文本与这些枚举常量相关联。

解决方案

  • 我给数据类和枚举类都添加了@Keep注释,如下所示:
@Keep
data class JournalData(
    val name: String,
    val url: String,
    val category: Categories
)

@Keep
enum class Categories { POLITICS, SPORTS, TECHNOLOGY }

通过这样做,您指定那些类和相应的属性/常量在启用缩小时不能被ProGuard修改。
此外,检查logcat将帮助您找到确切的错误。
另请参阅:

0
检查您在项目中使用的库的Proguard规则,也许您需要添加一些特定的规则。
在我的情况下,是因为混淆protobuf,下面的规则修复了这个问题。
-keep public class * extends com.google.protobuf.GeneratedMessageLite { *; }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接