由于我利用Gson和ActiveAndroID来保存数据,之前已经能顺利保存各种自定义类型。今天添加一种新的List自定义类型,之后sqlite疯狂报错,插入出现键重复:
我很清楚的记得以前绝对没这错误,而且这条数据绝对存在。
为啥用ActiveAndroID的Select出来是null? 我百思不得其解,由于一口气改了太多地方,一度怀疑是事务引起的,由于我用两个线程同时在加载数据,可能一个线程插入了,另一个线程也在 *** 作这数据,就怀疑ActiveAndroID的事务实现有BUG。
但是很快就排除了,因为数据库如果没这数据就算报错也应该有把数据插入成功的log,但是只有1条报错的log。说明数据库原来就有这数据。那么就是Select的问题。
通过仔细比较数据,发现有List<\String> picUrls的才会出错。就怀疑是不是数据有问题。
怀疑是序列化出了问题,因为我改过这里。
public class ListStringSerializer extends TypeSerializer { @OverrIDe public Class<?> getDeserializedType() { return List.class; } @OverrIDe public Class<?> getSerializedType() { return String.class; } @OverrIDe public String serialize(Object o) { // List<String> List<AtUser> List和T均可直接toString if (o == null) { return null; }// Log.i("ListStringSerializer",o.toString()); return o.toString(); } @OverrIDe public List<String> deserialize(Object o) { if (o == null) { return null; } Log.i("ListStringSerializer","deserialize:" + o.toString()); List<String> ret = null; try { ret = new Gson().fromJson((String) o,new Typetoken<List<String>>() { }.getType()); } catch (Exception ex) { Log.e("ListStringSerializer",Log.getStackTraceString(ex)); } Log.i("ListStringSerializer","deserialize ret:" + ret); return new Gson().fromJson((String) o,new Typetoken<List<String>>() {}.getType()); }}
这下终于报错了:
com.Google.gson.JsonSyntaxException: com.Google.gson.stream.MalformedJsonException: Unterminated array。
就能确定是数据的问题,导致无法正确序列号。坑爹的是ActiveAndroID对这个反序列化异常不打log也不报错,只是返回一个null。
这是原来的序列化代码:
import androID.util.Log;import com.activeandroID.serializer.TypeSerializer;import com.Google.gson.Gson;import com.Google.gson.reflect.Typetoken;import java.util.List;public class ListStringSerializer extends TypeSerializer { @OverrIDe public Class<?> getDeserializedType() { return List.class; } @OverrIDe public Class<?> getSerializedType() { return String.class; } @OverrIDe public String serialize(Object o) { if (o == null) { return null; } return new Gson().toJson(o); // ["string"] } @OverrIDe public List<String> deserialize(Object o) { if (o == null) { return null; } return new Gson().fromJson((String) o,new Typetoken<List<String>>(){}.getType()); }}
我今天蛋疼的把这里改了:
@OverrIDe public String serialize(Object o) { if (o == null) { return null; } return o.toString(); // [string] }
Gson对Json的语法检查还是很严格的,toString导致括号内的String少一对引号,所以不能被识别为String类型。
总结这个BUG之所以难调,是因为数据库里面有残留的错误格式的数据,导致Select一直为Null。我最开始就了怀疑这里,就把代码改回原样子,只是当时没有把数据库删除,导致残留数据无法select,发现BUG依然存在。就把这里排除掉了。真是没想到为啥ActiveAndroID对这里的异常不打Log,其他地方都打了。 最蛋疼的Java编程风格就是一个try-catch把异常都吃了,搞得出问题无从调试。所以宁愿每个函数后面都带throw也不要自己在中间过程的函数中吃了异常。
总结以上是内存溢出为你收集整理的最难调的Bug-序列化引起的血案全部内容,希望文章能够帮你解决最难调的Bug-序列化引起的血案所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)