Android上的Proguard和Netty 5 [英] Proguard and Netty 5 on Android

查看:90
本文介绍了Android上的Proguard和Netty 5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've seen a couple questions regarding this issue, but they are for older versions of Netty.
I have tried their answers, switching org.jboss.netty out with io.netty, but the same error occurs.

我正在尝试编译一个使用启用了Proguard的Netty 5.0.0Alpha2(内部版本16)的Android应用.

I'm trying to compile an Android app that uses Netty 5.0.0Alpha2 (build #16) with Proguard enabled.

没有Proguard,应用程序运行正常.
启用Proguard后,在尝试使用Netty时就会出现此异常:

Without Proguard, the app runs fine.
As soon as I enable Proguard, I get this exception when it tries to use 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配置:

This is my Proguard config:

# 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之类的可选依赖项.

I have tested it without the -dontwarn options to see if the warnings would point me in the right direction, but it's all missing optional dependencies like slf4j and Tomcat.

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

I have also tried excluding all the Netty classes like so:

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

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

...but that does not appear to fix it either.

推荐答案

在阅读了一些相当大的Netty资料后,我已经通过一些谨慎的*应用的Proguard规则解决了这个问题:

I have fixed this issue with some carefully* applied Proguard rules after reading through parts of the rather huge Netty sources:

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

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

My original exception was caused by the type variables being removed from the bytecode, which Netty uses via reflection. Signature in -keepattributes keeps this information.

如果您仅对 -keepattributes Signature ,则会出现稍微不同的异常-添加 InnerClasses 可以通过带回更多信息来解决此问题在类文件中.

You get a slightly different exception if you only do Signature on -keepattributes - adding InnerClasses fixes this one by bringing back even more information in the class files.

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

Later, I got java.lang.NoSuchFieldException: ctl; that's what -keepnames is for. This way, the field is still called ctl like Netty expects.

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

Finally, some members (like ctl, seen earlier) were being removed by Proguard because Netty only uses them via reflection. The final rule, -keepclasseswithmembers, makes sure Proguard doesn't remove them.

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

If you take this approach, I strongly recommend you use only the Netty jars you need, instead of the -all jar. Switching from -all to just the required Netty jars brought my method count way down after I had gone past the 65k limit. Reducing your jars requires bit of trial-and-error though as the separation is unclear and there's not really any resources saying what's what.

*一点也不仔细,我只是将规则拍入文件中,如果没有执行任何操作,则将其删除.可能有一种更好的方法可以将信息保留在整个程序中,而不是保留在Netty中.

* not carefully at all, I just slapped rules into the file and removed them if they did nothing. There's probably a better way to do this that doesn't keep this information in the entire program, but instead just Netty.

这篇关于Android上的Proguard和Netty 5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆