利用Gson和SharePreference存储结构化数据

具体的步骤

这个假设有三个User对象生成一个ArrayList<User>:

User user1 = new User("jack", "123456789", "http://www.hello.com/1.png");
User user2 = new User("tom", "45467956456", "http://www.hello.com/2.png");
User user3 = new User("lily", "65465897faf", "http://www.hello.com/3.png");
ArrayList<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);

利用Gson转化ArrayList<User>成Json Array数据:

Gson gson = new Gson();
String jsonStr = gson.toJson(users);
SPUtils.put(mContext, "USERS_KEY", jsonStr);

这里的jsonStr内容是:

[{"access_token":"123456789","profile_pic":"http://www.hello.com/1.png","username":"jack"},{"access_token":"45467956456","profile_pic":"http://www.hello.com/2.png","username":"tom"},{"access_token":"65465897faf","profile_pic":"http://www.hello.com/3.png","username":"lily"}]

这个时候看下sharepreference的xml文件里面有啥:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="USERS_KEY">[{&quot;access_token&quot;:&quot;123456789&quot;,&quot;profile_pic&quot;:&quot;http://www.hello.com/1.png&quot;,&quot;username&quot;:&quot;jack&quot;},{&quot;access_token&quot;:&quot;45467956456&quot;,&quot;profile_pic&quot;:&quot;http://www.hello.com/2.png&quot;,&quot;username&quot;:&quot;tom&quot;},{&quot;access_token&quot;:&quot;65465897faf&quot;,&quot;profile_pic&quot;:&quot;http://www.hello.com/3.png&quot;,&quot;username&quot;:&quot;lily&quot;}]</string>
</map>

发现String数据已经存储到了sharepreference中。那么该如何解析出来成bean对象呢?比如后面需要查jack这个人的对应的profile_pic:

String str = (String) SPUtils.get(mContext, "USERS_KEY", "");
users = gson.fromJson(str, new TypeToken<List<User>>() {}.getType());
for (User user : users) {
if (user.getUsername().equals("jack")) {
L.d(user.getProfile_pic());
}
}

在logcat中可以看到成功的打印出了Jack的profile_pic:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAR8AAAAfCAIAAABRQl6uAAADYUlEQVR4nO2awXWDMAyGu42xMkEmyCk3JuCclwHoBgzCErmxB52lBwgBWxZgLEKb/3scUvSqGFm/bDl8nQAAOny9ewAA/FugLgC0gLoA0ALqAkALqAsALVKqyxatKW4JHW6H6Grvrcmvq0zaxAWKLnX2/dNfF1poOiBvjPzO7KcuutSmrC0xcy+YNvKWL51lSxkiumVly0pIMB0KNvKUN9n3z9Gq80b+ubpsEayRgkmbD1eXE/lu2CavsvJwe5+NvNT1eDwej8cWX0dTF50rUzb2zH1j2LQDn6wuP/K2aLML9RqDukJ0SdMt8dn3j7lXRHR6LvrO1VUvwXR6FjlbtP39wHYilE+UN6HZckyUN8No/ceJMMUFqh/MqInyXUWoaxxkf8Ahuu7In5SQQzpXpqxtt8G7V91TsFPGxmetuoTckNOGSTm1epR4ZzgkxHO5H03J+rVr6vBq7270BXWtykJ/AEPnHWfiA8Q/1yRQlDeDT/6RV6rLFq3rcIHAhFwPOaRzZcrW3KvXBz/Oc4Nfpa5QbiwNb1fFNJd6xb7L+TNOXQs9LPfJmvq626dIY8805EGcSR5bKFC+ODkBr6ka58owd+a3xOyyLDucfnht9uQq5gx+3doVyA0hD8efdzi6VOy7dNS1qFlaexBPdMu6zMibrKhNfn3diTLJwwur65aVrbNv2ayuyXji9L/E4ay65GxOoa5+YEIevm3t+iPqWrR2rT3P6HuMy9Xea0u3rN/e1JYoziQPb0Zd4nzvs3bZgt9Ablm75K/eZ+1ymy7lE6Add4bexMyapuu428idwn2XcLQQMtmiNUXdmWzRZkU9pFecaXDrHAnIgRoXV5YEfdf08dkR9r0Tt86EHM6qa+ZIWez05Bg6uSFvvPc8U91PXSfnrInViXdmKFcaVl1xZ9ZjV/15l1PwVprGj+DflMrQtL46zfpak2P105cd4Wkoedx8sQ5ldc1Hfjx4tkJxgWVzQype45daAgFJyKHfM4x8YyjQkcsmoEryyEfkxpKdc1qSqcv/2Wr7ZcrWeF3+kn9h/0sw4VK9NCKfJDfGd1IJYcw/XLvAJ5DgTWjux+60HFpdAPxpoC4AtIC6ANAC6gJAC6gLAC2gLgC0gLoA0ALqAkALqAsALaAuALSAugDQ4heI8p7EFwHmyAAAAABJRU5ErkJggg==" alt="" />

如果需要存储的数据比较多,可以将每个Bean对象抽取出一个key(比如username)形成一个key的ArrayList,同时将这个key的ArrayList存储到SharePreferecene,方便后续取出bean对象。

方法23:存对象 (sharedPreferences+base64)

注意:
(1)这里的object必须implement Serializable这个接口。
(2)本质上这里使用的是String来存储对象,只是先将对象序列化为String了。

/**
* 将对象进行base64编码后保存到SharePref中
* @param key
* @param object
*/
public static void saveObj(Context context, String key, Object object) {
if (sp == null)
sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
// 将对象的转为base64码
String objBase64 = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
sp.edit().putString(key, objBase64).commit();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 将SharePref中经过base64编码的对象读取出来
* @param key
* @param defValue
*/
public static Object getObj(Context context, String key) {
if (sp == null)
sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
String objBase64 = sp.getString(key, null);
if (TextUtils.isEmpty(objBase64))
return null;
// 对Base64格式的字符串进行解码
byte[] base64Bytes = Base64.decode(objBase64.getBytes(), Base64.DEFAULT);
ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
ObjectInputStream ois;
Object obj = null;
try {
ois = new ObjectInputStream(bais);
obj = (Object) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}

方法22:保存List(Map(String, String)),(SharedPreferences+JsonArray )

原因:
SharedPreferences没有保存数组的方法,但是有时候为了保存一个数组而进行序列化,或者 动用sqlite都是有点杀猪焉用牛刀的感觉,所以就自己动手改进一下吧。

解决方案:方式是先转换成JSON,然后保存字符串,取出的时候再讲JSON转换成数组就好了。

public void saveInfo(Context context, String key, List<Map<String, String>> datas) {
JSONArray mJsonArray = new JSONArray();
for (int i = 0; i < datas.size(); i++) {
Map<String, String> itemMap = datas.get(i);
Iterator<Entry<String, String>> iterator = itemMap.entrySet().iterator();
JSONObject object = new JSONObject();

while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
try {
object.put(entry.getKey(), entry.getValue());
} catch (JSONException e) {

}
}
mJsonArray.put(object);
}

SharedPreferences sp = context.getSharedPreferences("finals", Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString(key, mJsonArray.toString());
editor.commit();
}

public List<Map<String, String>> getInfo(Context context, String key) {
List<Map<String, String>> datas = new ArrayList<Map<String, String>>();
SharedPreferences sp = context.getSharedPreferences("finals", Context.MODE_PRIVATE);
String result = sp.getString(key, "");
try {
JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); i++) {
JSONObject itemObject = array.getJSONObject(i);
Map<String, String> itemMap = new HashMap<String, String>();
JSONArray names = itemObject.names();
if (names != null) {
for (int j = 0; j < names.length(); j++) {
String name = names.getString(j);
String value = itemObject.getString(name);
itemMap.put(name, value);
}
}
datas.add(itemMap);
}
} catch (JSONException e) {
}
return datas;
}

方法21:保存Object或者ListObject (sharedPreferences+json)

Sharepreference是Android常用的数据存储技术,以key-value保存在手机本地,经常只是用来保存基本类型数据,
Google也只是提供putLong(),putBoolean(),putString()…实际项目中,我们经常是需要缓存Object或者ListObject,方便我们对App逻辑的操作,这时候我们就需要进一步封装,
利用Gson把Object或者ListObject转成String,用putString()保存,需要展示缓存内容时,get到String,利用Gson转成Object或者ListObject.
实际项目开发中,建议对Sharedpreference做成工具类,代码会简洁,直观。

存储Object对象

public void saveObject(String key, Object obj) {
SharedPreferences.Editor edit = settings.edit();
String str = gson.toJson(obj, obj.getClass());
edit.putString(key, str);
edit.commit();
}

获取存储Object对象

public <T> T getObject(String key, Class<?> classItem) {
try {
String str = settings.getString(key, null);
if (str != null) {
return (T) gson.fromJson(str, classItem);
}
} catch (Exception e) {

}

存储ListObeject对象
public <T> void saveListObject(String key, List<T> list) {
SharedPreferences.Editor edit = settings.edit();
String str = gson.toJson(list);
edit.putString(key, str);
edit.commit();
}
}

获取ListObeject对象
public List getListObject(String key,Class<?> classItem) {
JavaType javaType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, classItem);
try {
String str = settings.getString(key, null);
if (str != null) {
return mapper.readValue(str,javaType);
}
} catch (Exception e) {

}
return null;
}

以上是我在实际开发中,Sharedpreference 对Object和ListObject封装,欢迎交流指正。

方法2: 保存list( Json+SharedPrefernces ):

先把PlayList对象转换为JSON形式的字符串,用SharedPreferences来保存字符串。
/**
* 把播放列表转换为JSON形式以字符串形式保存
* @param object 播放列表对象
*/
public static void getJsonStringByEntity(Context context, Object object) {
String strJson = "";
Gson gson = new Gson();
strJson = gson.toJson(object);
saveSharePlayList(context,strJson);
}

读取出来的:
/**
* 读取播放列表数据
*/
public static PlayList getfromJson(Context context){
PlayList list = null;
String str = readSharePlayList(context);
if(str!=null){
Gson gson=new Gson();
list = gson.fromJson(str, new TypeToken<PlayList>(){}.getType());
}
return list;
}

方法1:依赖包:

直接转成String后再转回来降低了效率,这里有一个存储简单对象的编译时注解库:
https://github.com/2tu/fit 。
Fit 使用SharedPreferences存储对象中的基本数据类型。利用APT编译时生成代码,与转成String及反射相比更快。
支持:基本类型,基本包装类型,Set,minSDK 11。

SharePrecences--(json+sharePrecences)存list 或对象的更多相关文章

  1. ios 把数组对象转成json字符串存起来

    1第一步是我们获取数据源 一般我们都是从接口请求数据 NSArray *subColumnsArray = nil; NSDictionary *dict = [NSJSONSerialization ...

  2. json 串转成 java 对象再拼接成前台 html 元素

    获取商品参数 json 串,转成 java 对象,再拼接成前台 html 的Service方法 @Override public String getItemParam(Long itemId) { ...

  3. [MVC_Json序列化]Json字符串反序列化成C#对象

    上一篇中有Json序列化相关问题得到了解决. 那么结果集为Json串时,如何将Json串转成C#对象呢? 现举例说明: -现有如下字符串数据 string k = "{\"ring ...

  4. js中json字符串转成js对象

    json字符串转成js对象我所知的方法有2种: //json字符串转换成json对象 var str_json = "{name:'liuchuan'}"; //json字符串 / ...

  5. .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二)

    .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二) .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (一) 上一篇主 ...

  6. .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (一)

    .net core 1.1.0 MVC 控制器接收Json字串 (JObject对象) (二) Json是WEB交互常见的数据,.net core 处理方式是转为强类型,没有对应的强类型会被抛弃,有时 ...

  7. 类对象序列化为json串,json串反序列化为类对象

    1.类对象序列化为json串: 方法一: class P(object): def __init__(self,name,age,sex): self.name=name self.age=age s ...

  8. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  9. python 将一个JSON 字典转换为一个Python 对象

    将一个JSON 字典转换为一个Python 对象例子 >>> s='{"name":"apple","shares":50 ...

  10. JSON(JavaScript Object Notation, JS 对象标记)

    JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言 ...

随机推荐

  1. (利用tempdata判断action是直接被访问还是重定向访问)防止微信活动中用户绕过关注公众号的环节

    说明:这个不是在进行微信公众号开发,也就是说在不能获取用户openid的前提下做的下面操作 1.动机:最近有个微信活动(关注了服务号的可以免费领取礼品),要做这么一个功能,活动的入口在微信服务号的菜单 ...

  2. day27_反射

    1.反射-概述(掌握) 反射就是在程序运行过程中,通过.class文件动态的获取类的信息(属性,构造,方法),并调用 注意:JAVA不是动态语言,因为动态语言强调在程序运行过程中不仅能获取并调用类里面 ...

  3. html5原生canvas内image旋转

    目前理解下来就是旋转的不是image本身,而是要drawImage的那个canvas的2d context,context本身的绘制就是把图片本来的样子draw出来,至于旋转,透明度之类的效果都是对c ...

  4. Collections.reverse 代码思考-超越昨天的自己系列(13)

    点进Collections.reverse的代码瞄了眼,然后就开始了一些基础知识的收集. 现在发现知道的越多,知道不知道的越多. 列几个记录下: reverse方法源码: /** * Reverses ...

  5. C# DES进行加解密

    DES加解密 /// 进行DES加密. /// </summary> /// <param name="pToEncrypt">要加密的字符串.</p ...

  6. centos 安装beanstalkd

    You need to have the EPEL repo (http://www.servermom.org/2-cents-tip-how-to-enable-epel-repo-on-cent ...

  7. Cantor的数表

    题目描述 如下数列,前5项分别是1/1,1/2,2/1,3/1,2/2…….输入n,输出第n项. 1/1   1/2   1/3   1/4   1/5 2/1   2/2   2/3   2/4 3 ...

  8. 写给笨蛋徒弟的学习手册(1)——完整C#项目中各个文件含义

    Bin 目录用来存放编译的结果,bin是二进制binrary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin/R ...

  9. LintCode Min Stack

    用两个stack, 第一个按顺序放所有值,第二个只放当前最小值. 注意: 1. 最小值有多个则都放到两个stack里, 尤其别忘放第二个: 2. pop时若两个stack的最上面值相等则都pop, 不 ...

  10. Arduino101/Genuino101的安装入门

    1.首先下载Arduino IDE                      下载地址:http://pan.baidu.com/s/1gewqV2j 选择arduino-1.6.8-windows. ...