- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这是有问题的配置设置:-keep @interface *
这篇文章中引用了此设置:https://stackoverflow.com/a/17437740/367544
Proguard 手册中的此处:https://www.guardsquare.com/en/proguard/manual/troubleshooting#notkept
但手册(或帖子)并未解释此配置设置的工作原理或原因。我认为此配置值会保留在您的应用程序中定义 的任何注释。我在这里强调 defined 这个词是因为我想将它与 used 注释的地方进行比较。因此,如果我在我的代码中定义了一个注释,如 public @interface MyAnnotation {}
那么我希望这个配置设置能够保留它。但是,如果我要在另一个类中使用我的注释,如 public class MyClass { @MyAnnotation public void run(){} }
那么我不希望此配置设置保留在那里。我认为要在使用注释的地方保留注释,您需要像 -keep class * { @interface <methods>; }
这样的设置。 .但是,我的理解显然是错误的,因为 -keep @interface *
配置设置确实在使用的地方保留注释。
谁能解释为什么 -keep @interface *
配置设置会影响在其他类中使用的注释吗?此外,Proguard 手册从未解释如何使用 @interface
关键字。这就像任何注释的通配符吗?或者它是否像我的示例中那样引用注释的定义 public @interface MyAnnotation {}
?还是完全不同?
最佳答案
当每个接口(interface)都被编译时,即使使用混淆器,它也应该创建一个可以在 java 虚拟机中使用的有效类文件。Java 有特定的命名规则,用于将包中的接口(interface)和类与文件连接起来。
所以例如即使接口(interface)VeryImportantInterface
包裹数量 com.mycompany.mypackage
被混淆了,结果你得到:界面 a
在包装内 b.c.d
java 期望找到接口(interface) a
在包装内 b.c.d
在名为 a.class
的文件中
类似的规则适用于内部类和接口(interface)。
因此,如果您确实混淆了类或接口(interface)的定义,则必须在任何地方都提及其混淆后的名称。否则,例如类 MyClass.class
混淆为 a.class
和另一类,例如MyClassReference
仍将此类引用为 MyClass
然后是ClassNotFoundException
将在 MyClassReference
时抛出尝试使用 MyClass
第一次。
关于-keep @interface *如 ProGuard RefCard 中所述
'keep' prevents classes and class members from being removed or renamed.
ProGuard RefCard还提到通配符 *
可以用
*
can be used for any number of characters (but not the package separator)- the class name
*
refers to any class, irrespective of its package.*
matches any field or method
所以 -keep @interface *
根据以上定义适用于 public @interface MyAnnotation {}
因为它的名字匹配通配符 *
.因为根据定义 MyAnnotation
不会被删除,它不会从任何地方删除。
相反-keep class * { @interface <methods>; }
更具体,只会保留注释的用法。
要考虑的另一件事是 keep后面跟着一个 Class specification .并基于 Class specification
The @ specifications can be used to restrict classes and class members to the ones that are annotated with the specified annotation types. An annotationtype is specified just like a classname.
pro guard在收缩过程中会删除所有直接或间接使用的方法和成员加上-keep
指定的方法和成员.但是它没有明确提及它对注释的作用。Pro-Guard 提到缩小以下内容:
By default, shrinking is applied; all classes and class members are removed, except for the ones listed by the various -keep options, and the ones on which they depend, directly or indirectly. Shrinking Options So one case could be that pro-guard somehow detects that the annotation is used and prevents it from beeing removed during shrinking. Another case would be that the annotations are considered metadatum of the methods and not beeing considered members. It is really not obvious or well documented in proguard documentation.
您可以使用 -whyareyoukeeping @interface *
和 -verbose
从 Prog-Guard 获得有关保留相关接口(interface)的原因的反馈。
更新:由于上述配置指令的结果是: ... is kept by a directive in the configuration.
, 只能得出结论 -keep @interface *
实际上 。因此,它没有提供任何额外的说明。在没有对 Pro-Guard 文档进行任何具体解释的情况下,我认为可能有以下 2 种可能的解释:1. proguard shrinking step 认为注释在代码的某些部分使用,因此需要并且不减少。2. class_specification @interface *
匹配带注释的方法和注释声明。
关于java - 谁能解释 Proguard 配置设置 : -keep @interface *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49962245/
编写一个仅用于集中其他接口(interface)的接口(interface)是好的做法还是坏的做法? interface InterfaceA : InterfaceB, InterfaceC { }
有没有一种方法可以确定具体类型从任意接口(interface)列表?我知道类型转换,但我想知道所有满意的接口(interface)。 例如,给定: type Mover interface { Mo
我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface): package node type
这是我的代码: type IA interface { FB() IB } type IB interface { Bar() string } type A struct {
示例 A: // pseudo code interface IFoo { void bar(); } class FooPlatformA : IFoo { void bar() {
合并它编译的 leppies 反馈 - 但 IMO 有一些缺点,我希望编译器强制每个子类定义它们自己的 Uri 属性。现在的代码: [] type UriUserControl() = inh
我正在构建一个项目,该项目从用户那里获取一个术语,然后执行谷歌搜索并返回一个 json 格式的标题列表。 我正在使用 serpwow API 来执行谷歌搜索并试图解析响应。 但是我收到的错误是: pa
我只想在其他接口(interface)中实现某些接口(interface),我不希望它们能够被类直接继承。 提前致谢! 最佳答案 您不能在 C# 中执行此操作 - 任何类都可以实现它有权访问的任何接口
我是 Go 的新手,还有一些我还没有掌握的技巧 例如,我有一个可以这样调用的函数: myVar.InitOperation("foo",Operator.EQUAL,"bar") myVar.Init
我有一个通用接口(interface)来描述对输出流的访问,如下所示: interface IOutput { function writeInteger(aValue:Int):Void;
我正在做一个项目,我想通过某种接口(interface)(最好是 USB)将光电探测器电路安装到计算机上。但是,由于我是新手,所以我不知道应该朝哪个方向处理这个问题。假设我有一个带有 USB 连接的光
背景 我正在尝试创建一个简单的应用程序,以真正理解DDD + TDD + etc的整个堆栈。我的目标是在运行时动态注入DAL存储库类。这让我 域和应用程序服务层可测试。我打算用“穷人的DI”来完成 现
在 Java 中,接口(interface)扩展接口(interface)是完全合法的。 UML 中的这种关系看起来像“扩展”关系(实线、闭合、未填充的箭头)还是“实现”关系(虚线、闭合、未填充的箭头
我想创建一个具有相等和比较函数默认实现的接口(interface)。 如果我从类型 IKeyable 中删除所有内容除了Key成员,只要我不添加默认实现,它就是一个有效的接口(interface)。从
COM 中的双接口(interface)是能够通过 DispInterface 或 VTable 方法访问的接口(interface)。 现在有人可以告诉我这两种方法之间到底有什么区别吗? 我认为 V
我有一个类方法,它返回一个可以迭代的员工列表。返回列表的最佳方式是什么?通常我只返回一个 ArrayList。然而,据我了解,界面更适合这种类型的操作。哪个是最好使用的界面?另外,为什么返回接口(in
我想从包装类外部实例化一个内部非静态接口(interface)。 这可能吗? 考虑以下代码: shared class AOuterClass() { Integer val = 3; shared
我为一个类编写了一个接口(interface),如下所示: public interface IGenericMultipleRepository { Lazy> addresses { ge
我是 UML 的初学者,现在我正在创建一个序列图,问题是我想根据用户输入实现 DAO 接口(interface)。如何在时序图中正确绘制以实现接口(interface)。 最佳答案 您不会在 SD 上
要使用 jsr 303 验证创建有条件验证的组,请将接口(interface)类传递给注释,如下所示: @NotEmpty (groups={UpdateValue.class}) 我有很多不同的接口
我是一名优秀的程序员,十分优秀!