解决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 ...
随机推荐
- 20、android解决方案(转载)
目录: 1.广告 2.推送 3.云 4.统计 5.后端存储 6.地图 7.测试 8.托管 9.支付 10.音视频 11.社会化分享 12.存储 13.自动更新 14.轻开发 15.安全 16.图像 1 ...
- 【环境】VS2013和MATLAB相互调用混合编程
Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): 前一 ...
- css图片切换效果分析+翻译整理
Demos:http://tympanus.net/Tutorials/CSS3SlidingImagePanels/ 出处:http://tympanus.net/codrops/2012/01/1 ...
- 浅谈IT
在没有学计算机应用技术之前我对IT的认知度几乎为零,曾经还天真的认为IT就是白领,只要做上IT行业,以后便可高枕无忧.后来阴差阳错学了这个专业.通过一年的学习,虽然学艺不精但多少对IT行业了解的一知半 ...
- matrix_last_acm_1
password 123 A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/A 题意:n个数初始ai,m次操作 ...
- [haoi2010]订货 最小费用流
这道题oj上的标签是动态规划,但我想不出来动态规划怎么搞,空间不爆,时间也要爆的: 好的,不扯淡,此题正常做法是最小费用流: 这道题我写了两遍,为什么呢?原因是第一次写的时候,不会写费用流,又恰好没带 ...
- Discuz! X3.1去除内置门户导航/portal.php尾巴的方法
方法: 打开文件 /source/admincp/admincp_domain.php 查找 [php] if(!empty($domain) && in_array($domain, ...
- STMPClient 发送邮件显示 不允许使用邮件名称.
在.net 2.0,3.5, 针对某些邮箱(还不清楚是什么样的邮件) , 使用微软自带的DLL发送邮件会提示不允许使用邮件名称 .... 使用Jmail可以发送. 解决方案: 1. ...
- C#顺序表(数据结构)
xmfdsh我近来心情实在不好,只因为这两天课比较少,然后一下子时间太多,不知道干什么,心情郁闷......这是要闹哪样?这都让我一个郁闷了一个晚上.闲来无聊,回顾下之前学的C#数据结构,数据结构的重 ...
- 几个Google中国的访问IP
前面几个IP的访问速度比较快. 74.125.31.106 173.194.45.20 173.194.45.19 173.194.45.18 173.194.45.17 173.194.45.16 ...