Android上的Proguard和Netty 5

Una*_*Una 3 obfuscation android proguard netty

我已经看到了关于这个问题的几个问题,但它们适用于旧版本的Netty.
我已经尝试了他们的答案,用io.netty切换org.jboss.netty,但同样的错误发生了.

我正在尝试使用启用了Proguard的Netty 5.0.0Alpha2(build#16)编译一个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)
    ...
Run Code Online (Sandbox Code Playgroud)

这是我的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.**
Run Code Online (Sandbox Code Playgroud)

我已经在没有-dontwarn选项的情况下测试了它,看看警告是否会指向正确的方向,但是它们都缺少像slf4j和Tomcat这样的可选依赖项.

我也试过排除所有的Netty类,如下所示:

-keep class io.netty.** {
    *;
}
Run Code Online (Sandbox Code Playgroud)

......但这似乎也没有解决它.

Una*_*Una 8

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

-keepattributes Signature,InnerClasses
-keepclasseswithmembers class io.netty.** {
    *;
}
-keepnames class io.netty.** {
    *;
}
Run Code Online (Sandbox Code Playgroud)

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

如果您只是这样做Signature,您会得到一个略有不同的异常-keepattributes- InnerClasses通过在类文件中返回更多信息来添加修复此异常.

后来,我得到了java.lang.NoSuchFieldException: ctl; 这就是-keepnames的用途.这样,该领域仍然ctl像Netty所期望的那样被调用.

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

如果你采用这种方法,我强烈建议你只使用你需要的Netty罐子,而不是-all jar.从-all切换到只有所需的Netty的罐子把我的方法算下来,我已经走了过去的65K限制后.减少你的罐子需要一点反复试验,因为分离不清楚,并没有任何资源说什么是什么.

*根本不小心,我只是把规则打到文件中,如果他们什么都不做就删掉它们.可能有一种更好的方法可以将这些信息保存在整个程序中,而不仅仅是Netty.

  • 如果有人遇到这个问题 - "<class>不是@Sharable处理程序,所以不能多次添加或删除.",在-keepattributes列表中添加`*Annotation*`:`-keepattributes Signature,InnerClasses,*注释*` (3认同)

Yug*_*ugy 5

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

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

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

-keep public class io.netty.util.ReferenceCountUtil {
    *;
}
Run Code Online (Sandbox Code Playgroud)