Android上的Proguard和Netty 5

问题描述 投票:3回答:2

我已经看到了有关此问题的几个问题,但它们是针对Netty的旧版本的。我尝试了他们的答案,将org.jboss.netty与io.netty切换了出去,但是发生了同样的错误。

我正在尝试在启用Proguard的情况下编译使用Netty 5.0.0Alpha2(内部版本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)
    ...

这是我的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.** {
    *;
}

...但是这似乎也无法解决。

android netty proguard obfuscation
2个回答
8
投票

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

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

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

如果只对Signature进行-keepattributes,则会出现稍微不同的例外-添加InnerClasses会通过在类文件中带回更多信息来解决此问题。

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

最后,由于Netty仅通过反射使用它们,所以某些成员(如先前看到的ctl,已被Proguard删除)。最终规则-keepclasseswithmembers确保Proguard不会将其删除。

如果采用这种方法,强烈建议您仅使用所需的Netty jar,而不要使用-all jar。从-all切换到所需的Netty jars后,我的方法计数way降低了,超过了65k的限制。减少罐子需要一些反复试验,但由于分离尚不清楚,并且实际上没有任何资源可以说明是什么。

*一点也不仔细,我只是将规则拍入文件中,如果它们什么都不做,则将其删除。可能有一种更好的方法可以将信息保留在entire程序中,而不是保留在Netty中。


0
投票

Una的答案导致课程过多,这使我的应用比平常大1MB。因此,我使用以下规则:

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

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

-keepclassmembernames class io.netty.util.ReferenceCountUtil {
    *;
}
© www.soinside.com 2019 - 2024. All rights reserved.