Android数据绑定:为混淆的AAR

时间:2016-12-01 11:26:07

标签: android data-binding proguard aar

我想提供一个使用Android数据绑定的混淆AAR库。当我使用测试应用程序中的库时,只要图书馆没有被ProGuard缩小,一切正常。但是,启用ProGuard后,测试应用程序不再编译,因为无法找到生成的数据绑定类中的BR字段。

由于我无法找到关于此问题的任何官方文档,因此我们无法找到#34;主题,我试图了解Android数据绑定背后的魔力。机制似乎是这样的(请纠正我,如果我错了):

  • 为了在AAR lib中使用数据绑定,嵌入式应用程序也必须启用数据绑定。
  • 这是因为包含数据绑定指令的布局资源在AAR中未经修改而包含在内。
  • 因此,嵌入应用程序负责为lib中的布局生成相应的数据绑定类。 (这就是为什么lib的视图模型类不能被混淆的原因,顺便说一下。)
  • Android数据绑定生成器的挑战是告诉包名称与库和嵌入应用程序的区别:库的BR类必须在库的包中生成(例如com.example.lib。数据绑定),因为可以从库的视图模型类访问此类。另一方面,嵌入式应用程序的BR类通常应该在应用程序包中生成(com.example.app.databinding)。

这正是我的问题开始的地方。我不知道Android确实应对了这个挑战,我只知道在我的情况下,它适用于未经模糊处理的lib,并且它不会被混淆。当我查看嵌入式应用程序的生成源时,我看到:

  • 使用未经模糊处理的lib时,BR和所有* Binding.java类都在库的包中生成,并且应用程序将编译。
  • 使用混淆的lib时,BR和所有* Binding.java类都在应用程序包中生成。更糟糕的是,BR仅包含XML资源中模型变量名称的常量,而不包含视图模型类中的属性。因此,该应用程序无法编译。
  • 我尝试将数据绑定类的包显式设置为XML声明中的lib包,但这并不能解决BR类不完整的问题。

我不知道这些差异来自哪里,而且我不知道。已经担心唯一的解决办法就是从lib中删除所有我很好的数据绑定内容...有没有人提出类似的经验并且可以给我一个提示,好吗?

这些是我已经添加到我的lib中的ProGuard例外:

-keep public class **.BR { public *; }
-keep public class **.BR$* { public *; }
-keepclassmembers class **.BR$* {
    public static <fields>;
}
-keepclassmembers class **.R$* {
    public static <fields>;
}
-keep class android.databinding.** { *; }
-keep class * extends android.databinding.** { *; }
-keep class com.example.lib.databinding.** { *; }

2 个答案:

答案 0 :(得分:1)

我设法让它在此期间运行,但“解决方案”非常奇怪,我真的不想把它带到一个高效的版本......

比较混淆和未混淆的lib的AAR文件时,我注意到未混淆的文件的classes.jar包含这三个文件:

  • /com/example/lib/com.example.lib-br.bin
  • /com/example/lib/com.example.lib-layoutinfo.bin
  • /com/example/lib/com.example.lib-setter_store.bin

这些二进制文件包含一些我的数据绑定类名,对代码生成过程显然很重要。我只是试图将这些文件复制到我混淆的AAR的相应位置并且...它工作了!!!

但这不是最终的解决方案。如果我可以说服ProGuard简单地将这些非类文件保存在classes.jar中,那么至少它比应对更可靠。任何想法如何做到这一点?

我更希望获得有关该机制背景的一些信息,以及是否有可能避免这种丑陋的低级操作来解决实际应该是标准的问题。

提前感谢您的回答!

答案 1 :(得分:1)

显然Google已使用Gradle插件2.3.0解决了该问题,请参阅https://code.google.com/p/android/issues/detail?id=229684