Uber Engineering的Autoplue Extensions打开android捆绑包装

0.
Uber Engineering的Autoplue Extensions打开android捆绑包装

Android Bundle是一种方便,有时必要的对象,用于将数据包装到跨处理边界并发送意图,以及在配置变更之间存储状态。不幸的是,捆绑包中的包装数据通常需要重复和容易出错的代码。这使得这更糟糕的是,一个捆绑在于意图GCM.(Google云消息传递)失去类型信息,因为GCM将数据序列化为String-String键值对。

在研究如何消除Uber Android骑手应用的binding GCM对象的解绑定的解决方案时,我们意识到不仅提供的数据通常是只读的,而且还用于填充显示在通知上的数据,并为相应的待处理意图确定业务逻辑。这些对象是值类的主要例子;的实现的、最终的、不可变的类=哈希科特,toString.仅基于实例的状态。

生成值类使用简单AutoValue,它接受一个抽象类,该抽象类通过其定义其字段getter方法返回类型和名称,然后生成一个子类化界面的具体值类。AutoPulue还通过将它们链接在一起提供扩展框架。下面,我们提供了用于链接在一起的自动覆盖框架的示例:

$AutoValue_BundledObject extends $AutoValue_BundledObject {
// unbundle实现
}

$AutoValue_BundledObject扩展BundledObject {
// autovalue值类型实现
}

@autovalue.
公共抽象类BundledObject {
静态bundledobject create(...){
返回新的autovalue_bundledObject(...);
}
/ /抽象的属性
}

虽然存在自动扩展以处理重复Parcelable代码中没有针对Bundles的。为了在优步解决这个问题,我们创建并开放了资源AutoValue:包扩展。在本文中,我们讨论了我们的新工具的数据和处理类型干扰,使Android工程师能够将数据快速删除到值类中。此工具降低了遇到错误和迭代代码以及丢失类型信息的可能性,反过来改善了我们的Android用户的整体应用体验。

分开的数据

我们的autoployue:如果抽象基类注释,则将运行捆绑扩展@autovalue.还有一个公共静态方法,它返回带有两个参数的类类型:bundle和一个Gson实例。当它运行时,扩展生成一个典型的值类,但添加了一个静态unbundle方法,该方法以bundle和Gson实例为参数,并返回一个带注释的类的实例,如下例所示:

@autovalue.
公共抽象类foo {

公共静态foo创建(捆绑包,gson gson){
返回autovalue_foo.unbundle(捆绑,gson);
}

公共抽象字符串栏();
}

如上所述,autoPoLUE通常调用其子类构造函数来通过传递所有字段的值来创建新实例。但是,我们使用静态方法,因为我们只想采用两个参数,捆绑和Deserializer,Gson。unbdle方法将正确处理捆绑包上的正确获取方法。

在上面的例子中,它将调用bundle.getstring(“bar”)。与标准的AutoValue类类似,使用了返回类型和参数名称;但是,在这里它们决定了我们在bundle上调用哪个方法,以及我们传递什么String作为参数。方法名应该写成降低驼峰式大小写fooBar)并将转换为参数名称蛇的情况(foo_bar)。虽然这是一个严格的限制(有关这个主题的更多信息,请参阅“下一步”),但在命名参数时一定要记住,特别是当数据来自外部来源时。

GCM和类型推断

上面的简单版本处理数据存储在捆绑中的情况作为其正确类型;但是,如前所述,GCM以字符串字符串对序列化所有数据。要处理此操作,扩展名包括类级注释@GCMBundle从捆绑包读取所有数据作为字符串,然后使用原始类型解析或GSON实例转换为正确的返回类型。它甚至可以处理参数化对象,例如ArrayList

Gson实例将被用来解绑定其他对象类型,方法是从绑定包中获取String对象并使用TypeToken反序列化它。此外,生成的类还包含几个重载的辅助方法,“原语”,用于将字节、短、Char和Float数组转换为其原语数组的结果。这是因为Gson不能在没有自定义反序列化器的情况下从Json String读取基元类型数组。例如,如果一个字节数组存储在一个GCM Json字符串中,扩展将生成:

public static Test unbundle(Bundle Bundle, Gson Gson){/ /解绑定
返回新的AutoValue_Test(topprimitive (gson.fromJson(bundle.getString(" byte_array "), Byte[].class)))
}

原始字节(byte[] byteParam) {
byte [] bytes = new byte [byteparam.length];
For (int I = 0;我< byteParam.length;我+ +){
字节[i] = byteparam [i];
}
返回字节;
}

下一个步骤

随着我们继续增长AutoValue: Bundle扩展的功能,可能的添加包括:

  • 新的反序列化器:目前,扩展仅使用GSON支持反序列化;但是,它建立了支持多个Deserializer类。为此,我们将对象的反序列化包裹在Deserializer接口后面的反对化,该界面生成特定于解串化器的代码。我们计划为新的Deserializers添加支持,例如苎麻,通过在扩展类中更新适用方法并创建写入特定代码的新的解序机类。
  • 参数情况下规范:添加对参数案例规范的支持将允许更高的开发人员灵活性。实现这一点的一种可能的方法将是使用番石榴的案例形象作为注释的参数。

AutoValue: Bundle Extension是一个解决方案,我们构建它来生成代码,否则会很耗时且容易出错。通过简单地将AutoValue和扩展作为依赖项中的注释处理程序添加到项目中,如果您想使用@GCMBundle,还包括提供的扩展。

想要了解更多关于优步工程的开源努力,请查看我们的github页面!!

扎卡里·斯维加特(Zachary Sweigart)是优步拼车团队的安卓工程师。

图片标题:霓虹灯戈壁用Conor Myhrvold退出珊瑚头,博伊尔ABC群岛

评论