利用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. web框架思考

    以前一直不明白web框架是怎样实现路由.orm.接受请求的.今天看了下廖雪峰的python 实现web框架博客才明白. 简单总结并记录: http请求->wsgi->处理请求->返回 ...

  2. 也谈谈AlphaGo

    距离AlphaGo击败李世石已经过去数月了,心中的震撼至今犹在,全刊报道此项比赛的<围棋天地>杂志我已经看了不下十遍.总也想说点自己的意见,却也不知道从哪里说起,更不知道想表达些什么. 作 ...

  3. maven - Eclipse构建maven项目

    前面的博文已经介绍了如何安装maven,本文将记录如何在Eclipse下构建maven项目. 一.Eclipse maven插件安装 关于安装Eclipse maven插件,网上有很多方法,这里推荐一 ...

  4. LintCode MinStack

    Implement a stack with min() function, which will return the smallest number in the stack. It should ...

  5. iPhone应用开发 UITableView学习点滴详解

    iPhone应用开发 UITableView学习点滴详解是本文要介绍的内容,内容不多,主要是以代码实现UITableView的学习点滴,我们来看内容. -.建立 UITableView DataTab ...

  6. 什么是html技术

    HTML(Hyper Text Mark-up Language )即超文本标记语言,是 WWW 的描述语言,由 Tim Berners-lee提出.设计 HTML 语言的目的是为了能把存放在一台电脑 ...

  7. java的三大框架(一)

    现在许许多多的初学者和程序员,都在趋之若鹜地学习Web开发的宝典级框架:Struts2,Spring,Hibernate.似乎这些框架成为了一个人是否精通Java,是否会写J2EE程序的唯一事实标准和 ...

  8. sqlserver字段类型

    bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型, ...

  9. wince5代码整理

    BAT文件语法: @REM 这是注释标识与REM的区别就是在echo on时REM的注释也会显示出来 @REM 设置变量BSP_SMDK2416为2 set BSP_SMDK2416=2 @REM 设 ...

  10. 逻辑操作符“&&”的三层理解

    第一层:操作符“&&”可以对两个布尔值进行逻辑与运算,返回一个布尔值. 第二层:操作符“&&”可以对两个真假值进行逻辑与运算,并且返回一个真假值. 第三层:操作符“&a ...