【问题标题】:Android Data Binding: Wrong BR class generated for obfuscated AARAndroid 数据绑定:为混淆的 AAR 生成了错误的 BR 类
【发布时间】:2017-04-16 00:30:28
【问题描述】:

我想提供一个使用 Android 数据绑定的模糊 AAR 库。当我从测试应用程序中使用该库时,只要该库未被 ProGuard 缩小,一切正常。但是,启用 ProGuard 后,测试应用程序不再编译,因为在生成的数据绑定类中找不到 BR 字段。

由于我找不到任何关于这个“特定”主题的官方文档,我试图了解 Android 数据绑定背后的魔力。机制好像是这样的(如有错误请指正):

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

这正是我的问题开始的地方。我不知道 Android 到底能不能应对这一挑战,我只知道在我的情况下,它可以与未混淆的库一起使用,而不能与经过混淆的库一起使用。当我查看嵌入应用程序的生成源时,我看到:

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

我不知道这些差异来自哪里,而且我已经担心唯一的解决方案可能是从库中删除我所有漂亮的数据绑定东西......有没有人有类似的经历并可以给我一个提示,拜托?

这些是我已经添加到我的库中的 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.** { *; }

【问题讨论】:

    标签: android data-binding proguard aar


    【解决方案1】:

    我设法让它同时运行,但“解决方案”太奇怪了,我真的不想把它带到生产版本......

    比较混淆和未混淆库的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 中,至少它会比应对更可靠。任何想法如何做到这一点?

    如果能获得有关此机制背景的一些信息,以及是否有可能避免这种丑陋的低级操作来解决实际上应该是标准的问题,我将不胜感激。

    提前感谢您的任何回答!

    【讨论】:

    • 我已向 Android 团队提交了一个关于此问题的错误:
    • 是否有 Gradle 任务可以做到这一点...这超级烦人 :-(
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-04-05
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 1970-01-01
      • 2017-10-18
      • 2015-06-04
      相关资源
      最近更新 更多