Java 避免为房间类型转换器重新创建Gson实例
或者,问题的标题可以是:避免使用单例Util作为Java 避免为房间类型转换器重新创建Gson实例,java,android,architecture,gson,android-room,Java,Android,Architecture,Gson,Android Room,或者,问题的标题可以是:避免使用单例Util作为Gson包装器 在我使用Room for persistence的Android项目中,我有很多实体,其中某些列是非基本类型的。在四处查看了一会儿之后,我发现使用TypeConverter和Gson将非基本类型转换为字符串和字符串是一个不错的解决方案 现在,包含TypeConverters的类如下所示: class Converters { ... @TypeConverter public static Long fro
Gson
包装器
在我使用Room for persistence的Android项目中,我有很多实体,其中某些列是非基本类型的。在四处查看了一会儿之后,我发现使用TypeConverter
和Gson
将非基本类型转换为字符串和字符串是一个不错的解决方案
现在,包含TypeConverter
s的类如下所示:
class Converters {
...
@TypeConverter
public static Long fromDate(Date date) {
return date == null ? null : date.getTime();
}
@TypeConverter
public static Date toDate(Long timestamp) {
return timestamp == null ? null : new Date(timestamp);
}
@TypeConverter
public static String fromAddressData(AddressData addressData) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(AddressData.class, new AddressDataAdapter())
.create();
return gson.toJson(addressData);
}
@TypeConverter
public static AddressData toAddressData(String addressDataString) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(AddressData.class, new AddressDataAdapter())
.create();
return gson.fromJson(addressDataString, AddressData.class);
}
@TypeConverter
public static String fromUserData(UserData userData) {
Gson gson = new Gson();
return gson.toJson(userData);
}
@TypeConverter
public static UserData toUserData(String userDataString) {
Gson gson = new Gson();
return gson.fromJson(userDataString, UserData.class);
}
@TypeConverter
public static String fromCollectionData(CollectionData data) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(CollectionData.class, new CollectionDataAdapter())
.create();
return gson.toJson(data, CollectionData.class);
}
@TypeConverter
public static CollectionData toCollectionData(String dataString) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(CollectionData.class, new CollectionDataAdapter())
.create();
return gson.fromJson(dataString, CollectionData.class);
}
@TypeConverter
public static String fromRequestNoteList(List<RequestNote> noteList) {
Gson gson = new Gson();
return gson.toJson(noteList, RequestNote.LIST_TYPE);
}
@TypeConverter
public static List<RequestNote> toRequestNoteList(String noteListString) {
Gson gson = new Gson();
return gson.fromJson(noteListString, RequestNote.LIST_TYPE);
}
@TypeConverter
public static String fromRequestState(RequestState requestState) {
Gson gson = new Gson();
return gson.toJson(requestState);
}
@TypeConverter
public static RequestState toRequestState(String requestStateString) {
Gson gson = new Gson();
return gson.fromJson(requestStateString, RequestState.class);
}
...
}
然后,在转换器
类中,我可以使用反序列化器
,而不必每次都实例化一个相关的Gson
实例
除了单身人士被认为是邪恶的。当我说假设,我的意思是,由于我缺乏理解,我无法理解为什么这个设置是坏的。我的意思是,我知道这不是最好的解决方案,甚至不是很好的解决方案,但是如果不使用singleton作为拐杖,我想不出别的办法
反序列化器
不是一个适当的依赖项,而且,在我不知道的情况下,我想说可测试性不是一个问题,因为我看不到我想要伪造或存根反序列化器
所以我问题的第二部分是,;这个设置可以接受吗?还是它打破了清洁建筑的所有规则
在这种情况下,如果我不能向
转换器中注入依赖项,但我也不想继续重新创建Gson
实例,那么建议怎么做?针对转换器中的静态字段进行任何操作
private final static Gson Gson=new Gson()
?在需要的时候,你甚至可以使线程安全。”弗莱德最初在发布这个问题之前,我考虑过这个方法,并对它感到满意,直到我意识到这与使用单体没有什么不同。但是,既然你已经提到了,我认为这仍然是更好的方法,特别是考虑到房间TypeConverter
s都是静态的。是的,你是对的。它只不过比一个单身汉要简单。老实说,我看不出还有别的办法。可以考虑将它作为参数传递,但我假设房间自动调用这些方法,并且它们必须遵循特定的签名。
public class DeSerializer {
//Added formatters; please ignore the ignorance towards proper localization
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd, MMM, yyyy", Locale.ENGLISH);
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("dd, MMM, yyyy, hh:mm a", Locale.ENGLISH);
private static final DecimalFormat DISTANCE_FORMAT = new DecimalFormat("#.00 km");
//Singleton gson instance
private static Gson mGson;
public static Gson gson() {
if(mGson == null) {
synchronized (DeSerializer.class) {
if(mGson == null) {
mGson = new GsonBuilder()
.registerTypeAdapter(AddressData.class, new AddressDataAdapter())
.registerTypeAdapter(ImageData.class, new ImageDataAdapter())
.registerTypeAdapter(CollectionData.class, new CollectionDataAdapter())
.create();
}
}
}
return mGson;
}
//Gson wrapper methods
public static String toJson(Object src) {
return gson().toJson(src);
}
public static String toJson(Object src, Type typeOfSrc) {
return gson().toJson(src, typeOfSrc);
}
public static <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
return gson().fromJson(json, classOfT);
}
public static <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
return gson().fromJson(json, typeOfT);
}
public static <T> T fromJson(String json, TypeToken<T> typeTokenOfT) throws JsonSyntaxException {
return fromJson(json, typeTokenOfT.getType());
}
//Additional utility; please ignore the blurred boundaries of single responsibility
public static JsonObject jsonWebTokenPayload(String token) {
String[] parts = token.split("\\.");
String json = new String(Base64.decode(parts[1], Base64.URL_SAFE));
return gson().fromJson(json, JsonObject.class);
}
public static <T extends Parcelable> T getParcelable(Bundle data, String key, ClassLoader loader) {
data.setClassLoader(loader);
return data.getParcelable(key);
}
public static String dateString(Date date) {
return DATE_FORMAT.format(date);
}
public static String timeString(Date date) {
return TIME_FORMAT.format(date);
}
public static String datetimeString(Date date) {
return DATETIME_FORMAT.format(date);
}
public static String distanceString(Number distance) {
return DISTANCE_FORMAT.format((double) distance / 1000);
}
}