【问题标题】:okhttp3 minifyEnabled causes crash on Android 4.1.2okhttp3 minifyEnabled 导致 Android 4.1.2 崩溃
【发布时间】:2022-11-04 08:29:06
【问题描述】:

okhttp:3.12.13 中的此代码可与 minifyEnabled false 一起正常工作

  private static boolean supportsAlpn() {
    if (Security.getProvider("GMSCore_OpenSSL") != null) {
      return true;
    } else {
      try {
        Class.forName("android.net.Network"); //NoClassDefFoundError here if minifyEnabled true
        return true;
      } catch (ClassNotFoundException ignored) { }
    }
    return false;
  }

但使用minifyEnabled true 在Android 4.1.2 上会出现以下错误

Caused by: java.lang.ExceptionInInitializerError
    at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:292)
    at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
    at okhttp3.OkHttpClient.<init>(OkHttpClient.java:231)
Caused by: java.lang.ExceptionInInitializerError
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:217)
    at java.lang.Class.forName(Class.java:172)
    at okhttp3.internal.platform.AndroidPlatform.supportsAlpn(AndroidPlatform.java:219)
    at okhttp3.internal.platform.AndroidPlatform.buildIfSupported(AndroidPlatform.java:262)
    at okhttp3.internal.platform.Platform.findAndroidPlatform(Platform.java:246)
    at okhttp3.internal.platform.Platform.findPlatform(Platform.java:202)
    at okhttp3.internal.platform.Platform.<clinit>(Platform.java:78)
Caused by: java.lang.NoClassDefFoundError
    at android.net.Network.<clinit>(Unknown Source)

应该在Proguard 中添加哪些行以避免崩溃?

编辑:添加规则 12 没有帮助。

These rules 工作,但 apk 大小增加了 0.6 MB。

-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**

我想知道是否可以在不将所有 okhttp3 类保留在 apk 中的情况下解决此问题。

【问题讨论】:

    标签: android proguard okhttp


    【解决方案1】:
    【解决方案2】:

    我在使用 OkHttp 3.12.12 的 Android 4.1.1 上遇到了相同的问题,但是对 proguard 规则的建议修复并没有解决我的问题。

    有趣的是,NoClassDefFoundError 似乎来自 r8 捆绑在 APK 中的 android.net.Network 的副本,但包含以下异常代码(使用 apktool 反汇编):

    .class public synthetic Landroid/net/Network;
    .super Ljava/lang/Object;
    
    # interfaces
    .implements Landroid/os/Parcelable;
    
    
    # direct methods
    .method static synthetic constructor <clinit>()V
        .locals 1
    
        new-instance v0, Ljava/lang/NoClassDefFoundError;
    
        invoke-direct {v0}, Ljava/lang/NoClassDefFoundError;-><init>()V
    
        throw v0
    .end method
    

    这就是 NoClassDefFoundError 没有消息并且源自 clinit(静态初始化程序)的原因。

    这是一个相当疯狂的猜测,但也许 r8 会在内部为缩小阶段生成此代码,然后意外地将其具体化到 APK 中?所以看起来这可能是 r8 中的某种错误。

    不管实际有效的修复是不使用 Android Gradle 插件 7.3.X 而是恢复到 AGP 7.2.2。 AGP 7.4.0-beta04 似乎也可以工作。对于这些其他版本的 AGP,不寻常的 android.net.Network 类不会出现在 APK 中。

    【讨论】:

      猜你喜欢
      • 2020-11-16
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多