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同时使用,对象序列化失败的问题的更多相关文章

  1. 如何解决Android开发中的【java.lang.unsatisfiedlinkerror findLibrary returned null.】 错误

    将脉可寻的功能加入到自己的APP中时,需要在libs文件中添加.so文件和jar包 但是,加入.so文件后,仍然报错 在一番折腾之后,终于解决了,然而解决的方法很奇异- -. 在libs下新建一个ar ...

  2. Android开发中Eclispe相关问题及相应解决(持续更新)

    1.Eclipse项目中的Android Private Libraries没有自动生成. 一般而言,在Android开发中,项目中引用到的jar包会放到项目目录中的libs中,引入库会放到Andro ...

  3. Android开发中的问题及相应解决(持续更新)

    最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...

  4. Android开发中如何解决加载大图片时内存溢出的问题

    Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给 ...

  5. 如何解决android logcat不打印信息在android开发中

    用eclipse进行android开发中经常遇到logcat无任何信息输出,这给我们调试程序带来很大的不便.解决办法:window-->show view-->选择android下的dev ...

  6. 5个Android开发中比较常见的内存泄漏问题及解决办法

    android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了.   内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统 ...

  7. 在Android开发中替换资源图片不起作用的解决方法

    现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是 ...

  8. Android开发中常见的设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...

  9. Android开发中常见的设计模式 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

随机推荐

  1. 安装Symfony2

    我就不明白这个框架明明很小就几M,为什么这么难下载. 他们为什么不把文件打包好?非要搞得这么复杂. 一开始我在Linux ubuntu下载没有成功 然后想在win10上试试 到www.apache.o ...

  2. 3527: [Zjoi2014]力 - BZOJ

    题目大意:给出n个数qi,定义 Fj为        令 Ei=Fi/qi,求Ei. 看了很久题解,终于有些眉目,因为知道要用FFT,所以思路就很直了 其实我们就是要±1/(j-i)^2 ( j-i大 ...

  3. TCP 粘包/拆包问题

    简介    TCP 是一个’流’协议,所谓流,就是没有界限的一串数据. 大家可以想想河里的流水,是连成一片的.期间并没有分界线, TCP 底层并不了解上层业务数据的具体含义 ,它会根据 TCP 缓冲区 ...

  4. Codeforces Round #353 (Div. 2) D. Tree Construction 二叉搜索树

    题目链接: http://codeforces.com/contest/675/problem/D 题意: 给你一系列点,叫你构造二叉搜索树,并且按输入顺序输出除根节点以外的所有节点的父亲. 题解: ...

  5. bzoj 2956 数学展开,分段处理

    首先对于答案 ΣΣ(n mod i)*(m mod j) i<>j 也就是Σ(n mod i)Σ(m mod j)-Σ(n mod i)(m mod i) 将mod展开,我们可以得到有fl ...

  6. 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 ...

  7. ios 百度地图

    百度地图  中的注意事项 1. 百度地图中 使用了c++   设置buidSeting compoileSource 为 Object-C++  强制使用oc++编译器 2. 设置  BuidSeti ...

  8. YEBIS

    在往项目里加yebis做各种后处理 就是看起来很高大上的各种味精 我又热!泪!盈!眶!了 压缩包解开 有各种文档 恩哼~ 大概看了下找到sample build.... 直接就success了.... ...

  9. PHP 路径或URL操作

    echo 'documentroot:'.$_SERVER['DOCUMENT_ROOT'].'<br>'; //根目录,在apache的配置文件里定义:httpd.conf 比如:Doc ...

  10. Asp.net与Flex交互测试记录

    一.利用asp.net为Flex提供数据服务,flex为前端表现. 二.flex通过三种方式四种代码实现来取数据.分别为     HttpService. WebService. RemoteObje ...