【问题标题】:Proguard and Netty 5 on AndroidAndroid 上的 Proguard 和 Netty 5
【发布时间】:2015-01-20 21:58:30
【问题描述】:

我看到了几个关于这个问题的问题,但它们是针对旧版本的 Netty。
我已经尝试了他们的答案,将 org.jboss.netty 换成 io.netty,但出现了同样的错误。

我正在尝试编译一个使用 Netty 5.0.0Alpha2 (build #16) 并启用 Proguard 的 Android 应用程序。

没有 Proguard,应用程序运行良好。
启用 Proguard 后,它会在尝试使用 Netty 时出现此异常:

java.lang.IllegalStateException: unknown type parameter 'I': class io.netty.channel.SimpleChannelInboundHandler
    at io.netty.util.internal.TypeParameterMatcher.find0(Unknown Source)
    at io.netty.util.internal.TypeParameterMatcher.find(Unknown Source)
    at io.netty.channel.SimpleChannelInboundHandler.<init>(Unknown Source)
    at io.netty.channel.SimpleChannelInboundHandler.<init>(Unknown Source)
    ...

这是我的 Proguard 配置:

# billing
-keep class com.android.vending.billing.**

# butterknife
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector {
    *;
}
-keepnames class * {
    @butterknife.InjectView *;
}

# admob
-keep public class com.google.android.gms.ads.** {
    public *;
}

-keep public class com.google.ads.** {
    public *;
}

# logging
-assumenosideeffects class android.util.Log

# netty (partial)
-dontwarn io.netty.**
-dontwarn sun.**

我已经在没有 -dontwarn 选项的情况下对其进行了测试,以查看警告是否会为我指明正确的方向,但它都缺少 slf4j 和 Tomcat 等可选依赖项。

我也尝试过像这样排除所有 Netty 类:

-keep class io.netty.** {
    *;
}

...但这似乎也无法解决问题。

【问题讨论】:

  • 我不知道netty可以在Android设备上使用,谢谢

标签: android netty proguard obfuscation


【解决方案1】:

在阅读了部分相当庞大的 Netty 资源后,我已经通过一些仔细*应用的 Proguard 规则解决了这个问题:

-keepattributes Signature,InnerClasses
-keepclasseswithmembers class io.netty.** {
    *;
}
-keepnames class io.netty.** {
    *;
}

我最初的异常是由从字节码中删除的类型变量引起的,Netty 通过反射使用字节码。 Signature in -keepattributes 保留此信息。

如果你只在-keepattributes 上执行Signature,你会得到一个稍微不同的异常——添加InnerClasses 通过在类文件中带回更多信息来修复这个异常。

后来,我得到了java.lang.NoSuchFieldException: ctl;这就是 -keepnames 的用途。这样,该字段仍然像 Netty 预期的那样称为 ctl

最后,Proguard 删除了一些成员(如 ctl,如前所述),因为 Netty 仅通过反射使用它们。最终规则 -keepclasseswithmembers 确保 Proguard 不会删除它们。

如果您采用这种方法,我强烈建议您只使用您需要的 Netty jar,而不是 -all jar。在我超过 65k 限制后,从 -all 切换到仅需要的 Netty jar 会使我的方法计数方式下降。减少你的罐子需要一些反复试验,尽管分离不清楚,而且没有任何资源说明什么是什么。

* 一点也不小心,我只是将规则添加到文件中,如果它们什么也没做就删除它们。可能有更好的方法来做到这一点,它不会将这些信息保留在 整个 程序中,而是只保留 Netty。

【讨论】:

  • 如果有人遇到这个问题 - “ 不是@Sharable 处理程序,所以不能多次添加或删除。”,将*Annotation* 添加到-keepattributes 列表中:@ 987654332@
【解决方案2】:

Una 的回答保留了太多类,这使我的应用程序比平时大 1MB。所以我使用以下规则:

# netty
-keepclassmembernames class io.netty.buffer.AbstractByteBufAllocator {
    *;
}

-keepclassmembernames class io.netty.buffer.AdvancedLeakAwareByteBuf {
    *;
}

-keep public class io.netty.util.ReferenceCountUtil {
    *;
}

我已经在 Netty 4.1.63.Final 上测试了这些规则

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 2011-09-19
    • 2011-12-03
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多