从打包SDK的层面解决:Robolectric出现的java.lang.VerifyError

robolectroc出现了
java.lang.VerifyError

java.lang.VerifyError: Expecting a stackmap frame at branch target 37
Exception Details:
  Location:
   略
   @3: ifnonnull
  Reason:
    Expected stackmap frame at this location.
  Bytecode:
    0x0000000: b200 57c7 0022 122e 594b c2b2 0057 c700
    0x0000010: 0dbb 002e 59b7 006d b300 572a c3a7 0008
    0x0000020: 4c2a c32b bfb2 0057 b0                 
  Exception Handler Table:
    bci [11, 29] => handler: 32
    bci [32, 35] => handler: 32

本博客的上一章从使用的层面解决了该问题

就是在JVM 加入  -noverify
根本原因如下:

JVM 加载class文件时会做字节码校验(bytecode verification).如果你的class文件是由java源文件编译出来的,那么基本上不用担心bytecode verification. 如果class文件有asm,cglib等动态生成出来的或者由其他编译的,那么JVM在校验bytecode 时就会可能失败,失败的原因是可能生成的bytecode有bug,也可能是新版本的JVM加入了新的校验条件导致原来可以通过校验的bytecode 现在不成功了.在我自己例子中:使用jdk1.7打包的SDK,使用jdk1.8做Robolectric 测试就发生了java.lang.VerifyError
而对于使用者而已,我们-noverify就是关闭bytecode verification

####### 以下提供从SDK的层面上解决java.lang.VerifyError

关键是在混淆文件中删除- dontpreverify

本作者将混淆文件proguard-rules.pro的dontpreverify 注释打包之后,依然出现ava.lang.VerifyError

为什么呢?

打开build.gradle可见:

  buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
           
        }
    }

自定义混淆文件proguard-rules.pro中我已经注释了#- dontpreverify,这个getDefaultProguardFile('proguard-android-optimize.txt')是什么呢?

原来他是系统生成的混淆文件,我们点进去可见:

   public static File getDefaultProguardFile(@NonNull String name, @NonNull Project project) {
        if (!DEFAULT_PROGUARD_WHITELIST.contains(name)) {
            throw new IllegalArgumentException(
                    "User supplied default proguard base extension "
                            + "name is unsupported. Valid values are: "
                            + DEFAULT_PROGUARD_WHITELIST);
        }

        return FileUtils.join(
                project.getRootProject().getBuildDir(),//  根目录/build
                AndroidProject.FD_INTERMEDIATES,//  "intermediates"
                "proguard-files",
                name //'proguard-android-optimize.txt
                + "-" + Version.ANDROID_GRADLE_PLUGIN_VERSION);
    }

根据以上的代码,我在: 项目根目录/build/intermediates/proguard-files,找到了proguard-android-optimize.txt-2.3.3 该文件中有dontpreverify

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
-dontpreverify    # 需要注释

所以,我把这个文件放在SDK 的项目目录中,将# -dontpreverify注释掉,且在build.gradle 中引用该混淆代替系统的混淆

    buildTypes {
        release {
            minifyEnabled true
//            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            proguardFiles 'proguard-android-optimize.txt', 'proguard-rules.pro'

        }
    }

打包后即可解决verifyError 的问题

以下是使用的总结:

1.在根目录/build/intermediates/proguard-files下,复制proguard-android-optimize.txt-2.3.3文件到SDK下面
在这里插入图片描述

2.修改build.gradle

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles 'proguard-android-optimize.txt', 'proguard-rules.pro'

        }
    }
  1. 打包后就可以啦…(done)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值