创建Xamarin Android原生绑定时如何映射java.time.Instant至NodaTime.Instant
Xamarin.Android绑定java.time类型的替代方案
能否为java.time创建绑定库?
没必要单独为java.time创建绑定库。Xamarin.Android本身已内置对java.time的部分绑定,但受Xamarin.Android#8081问题影响,java.time.Instant这类类型的映射会出错。手动生成完整绑定不仅步骤繁琐,维护成本也高,不如直接用类型替换方案更高效。
用NodaTime替代java.time类型的实现方法
这是最可行的解决方案,通过绑定配置和自定义代码实现自动替换:
1. 引入依赖
在你的Xamarin.Android绑定项目中安装NodaTime NuGet包。
2. 调整Metadata.xml映射规则
修改绑定项目中的Metadata.xml,将目标java.time类型指定映射为NodaTime对应的类型。以java.time.Instant为例:
<!-- 替换字段类型 --> <attr path="/api/package[@name='你的Android库包名']/class[@name='目标类名']/field[@name='timestampField']" name="managedType">NodaTime.Instant</attr> <!-- 替换方法返回值类型 --> <attr path="/api/package[@name='你的Android库包名']/class[@name='目标类名']/method[@name='getTimestamp']" name="managedReturn">NodaTime.Instant</attr> <!-- 替换方法参数类型 --> <attr path="/api/package[@name='你的Android库包名']/class[@name='目标类名']/method[@name='setTimestamp']/parameter[@name='p0']" name="managedType">NodaTime.Instant</attr>
3. 添加类型转换代码
在绑定项目的Additions目录下创建对应类的扩展代码,实现NodaTime与java.time类型的双向转换:
public partial class 目标类名 { // 重写字段/属性,实现类型转换 public new NodaTime.Instant TimestampField { get => NodaTime.Instant.FromUnixTimeMilliseconds(Java.Lang.Long.ValueOf(TimestampFieldJava.ToString()).LongValue()); set => TimestampFieldJava = Java.Time.Instant.OfEpochMilli(value.ToUnixTimeMilliseconds()); } // 重写方法,适配参数和返回值 public new NodaTime.Instant GetTimestamp() { var javaInstant = base.GetTimestamp(); return NodaTime.Instant.FromUnixTimeMilliseconds(javaInstant.ToEpochMilli()); } public new void SetTimestamp(NodaTime.Instant instant) { var javaInstant = Java.Time.Instant.OfEpochMilli(instant.ToUnixTimeMilliseconds()); base.SetTimestamp(javaInstant); } }
4. 批量处理建议
如果库中大量使用java.time类型,可以通过Metadata.xml的通配规则批量替换,例如:
<attr path="/api/package[@name='你的Android库包名']//method[contains(returnType,'java.time.Instant')]" name="managedReturn">NodaTime.Instant</attr>
注意事项
- 其他java.time类型(如
LocalDate、ZonedDateTime)可参照此方法,对应替换为NodaTime的LocalDate、ZonedDateTime等类型 - 务必测试转换逻辑的准确性,比如时间戳的毫秒值、时区偏移等是否一致
- 若绑定生成过程中出现冲突,可通过Metadata.xml的
<remove>或<rename>标签调整
内容的提问来源于stack exchange,提问作者Kikanye
相关产品推荐
相关产品推荐

