解决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 ...
随机推荐
- 安装Symfony2
我就不明白这个框架明明很小就几M,为什么这么难下载. 他们为什么不把文件打包好?非要搞得这么复杂. 一开始我在Linux ubuntu下载没有成功 然后想在win10上试试 到www.apache.o ...
- 3527: [Zjoi2014]力 - BZOJ
题目大意:给出n个数qi,定义 Fj为 令 Ei=Fi/qi,求Ei. 看了很久题解,终于有些眉目,因为知道要用FFT,所以思路就很直了 其实我们就是要±1/(j-i)^2 ( j-i大 ...
- TCP 粘包/拆包问题
简介 TCP 是一个’流’协议,所谓流,就是没有界限的一串数据. 大家可以想想河里的流水,是连成一片的.期间并没有分界线, TCP 底层并不了解上层业务数据的具体含义 ,它会根据 TCP 缓冲区 ...
- Codeforces Round #353 (Div. 2) D. Tree Construction 二叉搜索树
题目链接: http://codeforces.com/contest/675/problem/D 题意: 给你一系列点,叫你构造二叉搜索树,并且按输入顺序输出除根节点以外的所有节点的父亲. 题解: ...
- bzoj 2956 数学展开,分段处理
首先对于答案 ΣΣ(n mod i)*(m mod j) i<>j 也就是Σ(n mod i)Σ(m mod j)-Σ(n mod i)(m mod i) 将mod展开,我们可以得到有fl ...
- bzoj 1041 圆上的整点 分类: Brush Mode 2014-11-11 20:15 80人阅读 评论(0) 收藏
这里先只考虑x,y都大于0的情况 如果x^2+y^2=r^2,则(r-x)(r+x)=y*y 令d=gcd(r-x,r+x),r-x=d*u^2,r+x=d*v^2,显然有gcd(u,v)=1且u&l ...
- ios 百度地图
百度地图 中的注意事项 1. 百度地图中 使用了c++ 设置buidSeting compoileSource 为 Object-C++ 强制使用oc++编译器 2. 设置 BuidSeti ...
- YEBIS
在往项目里加yebis做各种后处理 就是看起来很高大上的各种味精 我又热!泪!盈!眶!了 压缩包解开 有各种文档 恩哼~ 大概看了下找到sample build.... 直接就success了.... ...
- PHP 路径或URL操作
echo 'documentroot:'.$_SERVER['DOCUMENT_ROOT'].'<br>'; //根目录,在apache的配置文件里定义:httpd.conf 比如:Doc ...
- Asp.net与Flex交互测试记录
一.利用asp.net为Flex提供数据服务,flex为前端表现. 二.flex通过三种方式四种代码实现来取数据.分别为 HttpService. WebService. RemoteObje ...