解决Android开发中,ActiveAndroid和Gson同时使用,对象序列化失败的问题
ActiveAndroid是安卓开发常用的ORM框架。
Gson则是Google提供的轻量级序列化框架,非常适合Android开发使用。
但这两者同时使用,会产生序列化失败的问题。你通常会收到如下信息:
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: [your model]. Forgot to register a type adapter?
这是由于ActiveAndroid框架需要模型继承com.activeandroid.Model类,而这个类貌似不能序列化,具体原因未深究,有兴趣的同学可以看看ActiveAndroid的源码。
在ActiveAndroid的Git上查阅了Issue后,发现有开发者遇到类似问题,但没有有效解决办法。
翻阅了Gson API之后,发现Google已经提供了解决途径。
假设我们有一个基础类ClassBase:
import java.io.Serializable;
public class ClassBase implements Serializable {
/**
* -6454847757470885679L
*/
private static final long serialVersionUID = -6454847757470885679L;
private String name;
private int count;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
另有一个扩展类Cnblogs:
import java.io.Serializable;
public class Cnblogs extends ClassBase implements Serializable {
/**
* 8568957562120574502L
*/
private static final long serialVersionUID = 8568957562120574502L;
private String welcome;
private int members;
private String url;
public String getGuid() {
return welcome;
}
public void setGuid(String welcome) {
this.welcome = welcome;
}
public int getMembers() {
return members;
}
public void setMembers(int members) {
this.members = members;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
如果我们在序列化时想要忽略父类的属性,怎么办呢?
这时候,你需要com.google.gson.ExclusionStrategy接口来处理这个问题。
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes; public class SpecificClassExclusionStrategy implements ExclusionStrategy { private final Class<?> excludedThisClass;
private final Class<?> excludedThisClassFields; /***
* 过滤器初始化
*
* @param excludedThisClass
* 该类和继承自该类的对象实例将被忽略
* @param excluedThisClassFields
* 该类的属性将不被序列化
*/
public SpecificClassExclusionStrategy(Class<?> excludedThisClass, Class<?> excluedThisClassFields) {
this.excludedThisClass = excludedThisClass;
this.excludedThisClassFields = excluedThisClassFields;
} @Override
public boolean shouldSkipClass(Class<?> clazz) {
if (clazz == null) return false;
if (clazz.equals(excludedThisClass)) return true;
return shouldSkipClass(clazz.getSuperclass());
} @Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(excludedThisClassFields);
} }
再看看这个如何使用,
import com.google.gson.Gson;
import com.google.gson.GsonBuilder; public class Main { public static void main(String[] args) {
Cnblogs bl = new Cnblogs();
bl.setName("Cnblogs"); // 设置父类属性
bl.setCount(1); bl.setWelcome("代码改变世界"); // 设置当前类属性
bl.setMembers(176473);
bl.setUrl("http://www.cnblogs.com");
Gson gson = new Gson(); // 通常我们使用的初始化方法
System.out.println(gson.toJson(bl));
// 使用了过滤器的初始化方法
Gson gson2 = new GsonBuilder().setExclusionStrategies(new SpecificClassExclusionStrategy(null, ClassBase.class)).create();
System.out.println(gson2.toJson(bl));
} }
两条打印语句结果如下:
{"welcome":"代码改变世界","members":2030103,"url":"http://www.cnblogs.com","name":"Cnblogs","count":1}
{"welcome":"代码改变世界","members":2030103,"url":"http://www.cnblogs.com"}
因此,我们只需要在项目中,将gson实例的创建方式改为gson2,并将过滤类的构造函数第二个参数设为com.activeandroid.Model.class,序列化就成功了!
至于第一个参数,比如类A,则任何类A的实例或者继承自类A的类的实例,在序列化时都会返回null值,即不被序列化。
更复杂的序列化过滤规则,可以通过调整SpecificClassExclusionStrategy类中,两个重写方法来实现。
解决Android开发中,ActiveAndroid和Gson同时使用,对象序列化失败的问题的更多相关文章
- 如何解决Android开发中的【java.lang.unsatisfiedlinkerror findLibrary returned null.】 错误
将脉可寻的功能加入到自己的APP中时,需要在libs文件中添加.so文件和jar包 但是,加入.so文件后,仍然报错 在一番折腾之后,终于解决了,然而解决的方法很奇异- -. 在libs下新建一个ar ...
- Android开发中Eclispe相关问题及相应解决(持续更新)
1.Eclipse项目中的Android Private Libraries没有自动生成. 一般而言,在Android开发中,项目中引用到的jar包会放到项目目录中的libs中,引入库会放到Andro ...
- Android开发中的问题及相应解决(持续更新)
最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...
- Android开发中如何解决加载大图片时内存溢出的问题
Android开发中如何解决加载大图片时内存溢出的问题 在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...
- 如何解决android logcat不打印信息在android开发中
用eclipse进行android开发中经常遇到logcat无任何信息输出,这给我们调试程序带来很大的不便.解决办法:window-->show view-->选择android下的dev ...
- 5个Android开发中比较常见的内存泄漏问题及解决办法
android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了. 内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...
- 在Android开发中替换资源图片不起作用的解决方法
现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是 ...
- Android开发中常见的设计模式
对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...
- Android开发中常见的设计模式 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- asp.net中父子页面通过gridview中的按钮事件进行回传值的问题
这两天写BS程序,遇到父子页面传值的问题,以前没写过web系统,用了几天时间才将问题解决,总结下记录下来: 问题描述: 父页面A中有一个gridview,每行6个列,有5列中均有一个按钮,单击按钮,会 ...
- python 关键字参数
原文地址:http://docs.pythontab.com/python/python3.4/controlflow.html#tut-functions 函数可以通过 关键字参数 的形式来调用,形 ...
- PDO应用
<?php //PDO:数据访问抽象层//dsn:数据源://带有事务功能:$dsn = "mysql:host=localhost;dbname=mydb"; ——建立数 ...
- java 解决JFrame不能设置背景色的问题 分类: Java Game 2014-08-15 09:48 119人阅读 评论(0) 收藏
这段时间比较多,于是写一写JAVA的一些IT技术文章.如有JAVA高手请加QQ:314783246,互相讨论. 在Java的GUI设计中,Frame和JFrame两者之间有很大差别,上次刚学时编一个窗 ...
- CoreText 使用教程
[iOS开发] CoreText 使用教程:以创建一个简单的杂志应用为例抢沙发 分类:iPhone开发 标签:CoreText.iOS.iOS开发.iOS开发教程.杂志应用 BBS.CHINAAPP. ...
- JavaScript在IE6,IE7下报错'expected identifier, string or number'
问题: 代码在Forefox和IE8下工作正常,但是在IE6下报错: expected identifier, string or number 假如变量options有多个选项,那么我们可以用逗号分 ...
- PowerDesigner(五)-概念数据模型(CDM生成LDM,PDM和OOM)(转)
概念数据模型 概念数据模型(Conceptual Data Model,CDM):表达的是数据整体逻辑结构,该结构独立于任何软件和数据存储结构,即它只是系统分析人员,应用程序设计人员,维护人员和用户之 ...
- Base64编解码Android和ios的例子,补充JNI中的例子
1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: // Base64 编码: byte [] encode = ...
- Smarty模板学习
1.基本语法 所有的smarty模板标签都被加上了定界符.默认情况下是 { 和},但它们是可被改变的. 在smarty里,所有定界符以外的内容都是静态输出的,或者称之为不可改变.当smarty遇到了模 ...
- datagridview 点击列标题排序
开发winform中,平时经常用到数据列表,我们大多选用datagridview,但是此控件本身没有排序的功能.参阅网上资料.留下标记,以后备用. datagridview的数据显示一般是通过数据绑定 ...