【问题标题】:java.lang.VerifyError: Rejecting class that attempts to sub-class erroneous classjava.lang.VerifyError:拒绝尝试对错误类进行子类化的类
【发布时间】:2018-06-26 08:05:11
【问题描述】:

在将 proguard 应用于应用程序 m 时出现以下验证错误,我看到了其他验证错误变体,但以下似乎有点不同, Proguard 版本:5.3.3, 以下 MainApplication 类扩展了 android.app.Application 并在 super.onCreate() 处发生崩溃; onCreate() 方法

在我的 proguard m 中有

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgent

,我也提到过

-不要收缩 -不要优化

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapplication, PID: 18598
    java.lang.VerifyError: Rejecting class com.myapplication.MainApplication that attempts to sub-type erroneous class ak (declaration of 'com.myapplication.MainApplication' appears in /data/app/com.myapplication-v4oPXfQv5kNLX1oUA9GwUw==/base.apk)
        at java.lang.Class.newInstance(Native Method)
        at android.app.Instrumentation.newApplication(Instrumentation.java:1102)
        at android.app.Instrumentation.newApplication(Instrumentation.java:1087)
        at android.app.LoadedApk.makeApplication(LoadedApk.java:983)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5715)
        at android.app.ActivityThread.-wrap1(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        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)
     Caused by: java.lang.VerifyError: Rejecting class ak that attempts to sub-type erroneous class en (declaration of 'ak' appears in /data/app/com.myapplication-v4oPXfQv5kNLX1oUA9GwUw==/base.apk)
        at java.lang.Class.newInstance(Native Method) 
        at android.app.Instrumentation.newApplication(Instrumentation.java:1102) 
        at android.app.Instrumentation.newApplication(Instrumentation.java:1087) 
        at android.app.LoadedApk.makeApplication(LoadedApk.java:983) 
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5715) 
        at android.app.ActivityThread.-wrap1(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        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) 
     Caused by: java.lang.VerifyError: Verifier rejected class en: void en.<init>(android.content.Context) failed to verify: void en.<init>(android.content.Context): [0xA] thrown class Precise Reference: bjp not instanceof ThrowableVerifier rejected class en: void en.attachBaseContext(android.content.Context) failed to verify: void en.attachBaseContext(android.content.Context): [0x7] thrown class Precise Reference: bjp not instanceof Throwable

通过分析 apk,我可以看到没有 proguard 就不会混淆以下内容

.class public Lcom/myapplication/MainApplication;
.super Landroid/app/Application;
.source "MainApplication.java"

但是一旦我应用了proguard,同样会被混淆,

.class public Lcom/myapplication/MainApplication;
.super Lak;
.source "SourceFile"

如果我错了,请纠正我, 跟随

-keep public class * extends android.app.Application

它不能混淆应用程序类,为什么会发生上述情况..?

【问题讨论】:

  • 我在上面的应用中使用proguard这么久了,从来没有遇到过这样的问题,这一切都是在将Gradle插件版本更新到3.1.3之后发生的
  • 尝试添加选项-verbose,然后粘贴控制台输出(以防您无法弄清楚它试图告诉您什么)。您拥有的一条规则应该保留课程,以便在Manifest.xml 中引用。看到mapping.txt 一次,erroneous class ec 到底是什么。
  • @MartinZeitler 从映射文件我可以看到 android.app.application 映射到 android.app.Application -> ak: 20:20:void () -> 和类"en" 映射到 android.content.ContextWrapper -> en:
  • @MartinZeitler m 不确定为什么 android 默认类会被混淆,包括 android.os.Environment、android.os.Handler
  • 现在开始出现 java/lang/stringbuilder java.lang.NoSuchMethodError: No virtual method a(Ljava/lang/Object;)Ljava/lang/StringBuilder; 的 NoSuchmethod 错误在类 Ljava/lang/StringBuilder 中;或其超类('java.lang.StringBuilder' 的声明出现在 /system/framework/core-oj.jar 中)

标签: android proguard android-proguard


【解决方案1】:

在解决了很多冲突和变基后,我遇到了完全相同的错误。我刚刚清理了项目并重建了它。它又像魅力一样工作了。

【讨论】:

    【解决方案2】:

    在查看ContextWrapper 时……有人说:

    已知的直接子类

    应用程序、BackupAgent、ContextThemeWrapper、IsolatedContext、MutableContextWrapper、RenamingDelegatingContext、服务

    ...其中并非全部都在您的 ProGuard -keep 配置中声明。

    您需要添加一个类似于下面的规则,这是一种不同的方法,而不是按名称显式添加所有单独的子类...... public 关键字在那里相当可选,因为那些 @987654324 @/protected 方法实际上不需要被混淆,只是因为 SDK 源包是公开的可供下载的。在配置中添加-verbose 开关总是会让 ProGuard 抱怨“做什么”,总是带有用户手册的超链接。

    -keep public class * extends android.content.ContextWrapper {public *;}
    

    在处理混淆构建中的崩溃时,将 mapping.txt 上传到 Crashlytics 会有所帮助。

    【讨论】:

    • 肯定会在上面尝试
    • 修复了上面的问题,我注意到了一些新问题,使用 mapping.txt 我可以看到原生 Android 被混淆了,包括 android.os.Environment、Handler 和原生 java 类 java.lang.StringBuilder,m 不是确定为什么上面的类被混淆了
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多