ProGuard 导致 NullPointerException

Posted

技术标签:

【中文标题】ProGuard 导致 NullPointerException【英文标题】:ProGuard leads to NullPointerException 【发布时间】:2017-05-16 17:47:52 【问题描述】:

在我的 gradle 中设置 minifyEnabled true 时,我在启动我的应用程序时收到 NullPointerException

java.lang.RuntimeException: Unable to start activity ComponentInfode.ae.formulaecalendar/de.ae.formulaecalendar.view.calendar.CalendarActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2444)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504)
   at android.app.ActivityThread.-wrap11(ActivityThread.java)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1367)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:5461)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
   at de.ae.formulaecalendar.view.calendar.CalendarActivity.onCreate(Unknown Source)
   at android.app.Activity.performCreate(Activity.java:6251)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504) 
   at android.app.ActivityThread.-wrap11(ActivityThread.java) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1367) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:148) 
   at android.app.ActivityThread.main(ActivityThread.java:5461) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

在阅读 *** 时,我发现了 proguard-rules.pro 文件的一些设置:

######### KEEP ANDROID SUPPORT V7 AND DESIGN
-keep class android.support.v7.**  *; 
-keep interface android.support.v7.**  *; 

这并没有真正解决这个问题(但之前的 NullPointerException)。

最后是我 gradle 的重要部分:

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

当我解除 minifyEnabled 时,一切正常。

感谢您的帮助!

【问题讨论】:

这个问题对我来说有点不清楚。保留类确实解决了空指针异常?可以发一下CalendarActivity.onCreate()的代码吗? 请发SSCCE。 @Reaz Murshed:在此 NullPointerException 发生之前,之前有一个由 ProGuard 引起的,我可以通过发布的 proguard 规则解决。但是这些规则对这个 NullPointerException 没有帮助,我不知道为什么。抱歉,如果不清楚。我添加了 onCreate 和布局 xml。 @m0skit0: 我会努力做一个 常用Android库的Proguard规则proguard-rules 【参考方案1】:

当序列化对象并且字段没有被@SerializedName("param")(或类似的)注释并且因此无法找到时,很可能会发生这种情况。

对于调试,它还有助于临时设置-keepnames class **,这样类名就不会被混淆。

【讨论】:

调试提示很有帮助,告诉我出了什么问题【参考方案2】:

对我来说,添加行(您可能在放置 POJO 文件的地方使用其他包名称):

-keep class [mypackagename].model.**  *; 
-keep class [mypackagename].datamodel.**  *; 

proguard.rules 工作得很好,然后选项:

android

    ...

    buildTypes 

        release 

            minifyEnabled true 
            shrinkResources true

        
    

设置在build.gradle(模块:app)

【讨论】:

【参考方案3】:

我们的想法是保留项目中包含的库中提供的文件。我正在分享我的proguard-rules.pro 之一,它可能会帮助您理解。

-keep class com.google.**  *; 
-keep class com.github.**  *; 
-keep class org.apache.**  *; 
-keep class com.android.**  *; 
-keep class junit.**  *; 
-keep class android.support.v7.widget.SearchView  *; 
-keep class com.myproject.model.**  *; 

希望有帮助!

【讨论】:

感谢您的回答。对我来说,它似乎找不到android.support.v7.widget.RecyclerViewandroid.support.v7.widget.RecyclerView.LayoutManager,它们是我项目中包含的库之一(compile 'com.android.support:recyclerview-v7:25.0.0')的一部分。这就是为什么我将-keep class android.support.v7.** *; 添加到我的proguard 规则中,但没有成功。 您还需要保持课程以com.android. 开头。检查我添加的列表。这些是您需要保留的常用课程。 我解决了。这是 gradle 文件中 shrinkResources 的问题。不过,感谢您的帮助。我学到了一些关于 ProGuard 的知识。 这个规则集太松散了。您不妨完全关闭 proguard。【参考方案4】:

大部分时间是因为android libs的错误,试试这个

-keep interface android.support.**  *; 
-keep class android.support.**  *; 

【讨论】:

【参考方案5】:

我解决了这个问题:

在 Android Studio 中运行 Clean Project 后,我收到一个关于找不到名为 resource-release-stripped.ap_ 的文件的错误。通过 Google 进行的一些搜索显示我需要在 gradle 文件中禁用 shrinkResources,因为它与 Jack 不兼容。

【讨论】:

以上是关于ProGuard 导致 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

Proguard导致崩溃

Proguard导致杰克逊错误

ProGuard 导致 NullPointerException

Proguard 在构建发布 apk 时导致错误

Failed to start bean ‘documentationPluginsBootstrapper‘; nested exception is java.lang.NullPointerEx

启用 ProGuard 会导致签名 APK 生成失败?