仿京东商城系列9------购物车数据存储器实现

本项目来自菜鸟窝,有兴趣者点击http://www.cniao5.com/course/

项目已经做完,
https://github.com/15829238397/CN5E-shop


仿京东商城系列0------项目简介
仿京东商城系列1------fragmentTabHost实现底部导航栏
仿京东商城系列2------自定义toolbar
仿京东商城系列3------封装Okhttp
仿京东商城系列4------轮播广告条
仿京东商城系列5------商品推荐栏
仿京东商城系列6------下拉刷新上拉加载的商品列表
仿京东商城系列7------商品分类页面
仿京东商城系列8------自定义的数量控制器
仿京东商城系列9------购物车数据存储器实现
仿京东商城系列10------添加购物车,管理购物车功能实现
仿京东商城系列11------商品排序功能以及布局切换实现(Tablayout)
仿京东商城系列12------商品详细信息展示(nativie与html交互)
仿京东商城系列13------商品分享(shareSDK)
仿京东商城系列14------用户登录以及app登录拦截
仿京东长城系列15------用户注册,SMSSDK集成
仿京东商城系列16------支付SDK集成
仿京东商城系列17------支付功能实现
仿京东商城系列18------xml文件读取(地址选择器)
仿京东商城系列19------九宫格订单展示
仿京东商城系列20------终章


前言

如果有如果淘宝,或者京东的相信大家都知道,购物车可以存储用户的选择但未付款的订单。那就说明我们需要一个存储器来完成这项任务。由于条件限制,本例采用SharedPreferences进行数据存储。在实际运行中这些信息应当在本地和云端同时存贮。但这并不影响本例的研究,我们之研究封装功能的方法。

基础了解

在开始研究之前我们先对android为我们提供的数据存储机制,做一简单的了解。
在Android系统中,主要有五种数据存储模式:

1 .Sharedferences:Sharedferences是一种轻型的数据存储方式,本质上是基于XML文件存储key-value键值对数据。通常用来存储一些简单的配置信息;

2 .File:使用文件进行数据存储;

3 .SQLite:SQLite是一个轻量级的数据库,存储结构化的数据,支持基本SQL语法,是常被采用的一种数据存储方式。Android为SQLite提供了一个名为SQLiteDatabase的类,封装了一些CRUD操作的API;

4 .ContentProvider:ContentProvider为存储和获取数据提供统一的接口,可以在不同的应用程序之间共享数据;

5 .Network:使用基于网络的服务获取数据。

其中,前四种为本地数据持久化的存储方式。

当应用程序只有少量数据需要保存,而且这些数据的格式很简单,譬如都是String、Int、Long、Float和Boolean等简单数据类型时,可以使用SharedPreferences来保存,常用于保存应用程序的各种配置信息(是否使用振动效果、字体大小等);

当应用程序只有少量数据需要保存,而且这些数据的格式比较复杂,可以使用普通文件保存;

当应用程序有大量数据需要存储和访问,就可以使用SQLite数据库来保存。SQLite是一个真正轻量级的数据库,它没有后台进程,整个数据库就对应于一个文件;

当应用程序需要引用其他应用程序如多媒体播放、通讯录等的数据时,可以使用ContentProvider来调用数据接口;

当应用程序需要的数据需要跨设备和持久保存,就不能保存在本地,而应该采用网络服务器存储数据。

本文主要讲解SharedPreferences的使用与应用。

一. SharedPreferences的重要方法

1 . 读取SharedPreferences数据的方法

方法描述

boolean contains (String key)判断SharedPreferences是否包含特定key的数据。

abstract MapgetAll()获取SharedPreferences数据中全部的键值对数据集合。

abstract Xxx getXxx(String key, Xxx defaultValue)获取SharedPreferences数据里指定key对应的value。如果key不存在,则返回defaultValue。其中,Xxx可以是boolean、int、float、long、String。

abstract SetgetStringSet(String key, SetdefValues)获取SharedPreferences数据中指定key对应的Set值。

  1. 向SharedPreferences写入数据的方法

SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过通过SharedPreferences的内部接口SharedPreferences.Editor实现的。SharedPreferences调用edit()方法即可获取它对应的Editor对象。其中Editor对象向SharedPreferences写入数据的方法如下:

方法描述

abstract SharedPreferences.Editor

putXxx(String key, Xxx value)向Editor对象存入指定key对应的value数据。其中,Xxx可以是boolean、int、float、long、String。

abstract SharedPreferences.Editor

clear()清空Editor对象中的数据。

abstract SharedPreferences.Editor

remove(String key)删除Editor对象中指定的key对应的数据。

abstract SharedPreferences.Editor

putStringSet(String key, Setvalues)向Editor对象存入指定key对应的Set值。

abstract boolean commit()当Editor对象编辑完成后,调用该方法提交修改。

abstract void apply()提交Editor对象的修改。

二. 向SharedPreferences中存储数据

SharedPreferences本身是一个接口,不能直接创建SharedPreferences实例,可以通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例。其中,该方法中的mode参数可取的值有:

Context.MODE_PRIVATE:指定SharedPreferences数据只能被本应用程序读、写;

Context.MODE_WORLD_READABLE:指定SharedPreferences可被其他应用程序读,但不能写;

Context.MODE_WORLD_WRITABLE:指定SharedPreferences数据可被其他应用程序读、写。

实现SharedPreferences存储的步骤如下:

1 . 创建SharedPreferences对象;

2 . 创建SharedPreferences.Editor对象,用于存储数据修改;

3 . 通过Editor对象的putXxx()方法,存储key-value对数据信息;

4 . 通过Editor对象的commit()方法提交对SharedPreferences的修改。

实例如下:

/*

  • 创建SharedPreferences实例

  • 其中"myPref"指SharedPreferences数据的XML文件名

  • 指定该SharedPreferences数据只能被本应用程序读写

*/SharedPreferences pref = getSharedPreferences("myPref", MODE_PRIVATE);
// 创建SharedPreferences.Editor对象,用于存储数据修改
SharedPreferences.Editor editor = pref.edit();
// 存储数据信息editor.putString("name","zhangsan");editor.putInt("age",22);
editor.putLong("time", System.currentTimeMillis());editor.putBoolean("default",true);
// 提交数据修改editor.commit();

这样就完成了SharedPreferences的数据写入了。

在Android Studio的DDMS中可以查看"myPref"XML文件信息。myPref.xml所在的文件目录为 "/data/data/<包名>/shared_prefs/myPref.xml" 。DDMS的打开步骤如下:

"Tools"菜单 ->"Android"菜单 ->"Android Device Monitor"菜单,即可打开DDMS。

在DDMS中查看Android虚拟机下对应的"/data/data/<包名>/shared_prefs/myPref.xml",并导出myPref.xml至本地电脑中查看,可看到myPref.xml文件内容如下:

zhangsan

三. 读取本应用程序的SharedPreferences

所有创建的SharedPreferences数据都可以被本应用访问并进行读写操作。

实现SharedPreferences读取的步骤如下:

1 . 获取SharedPreferences对象;

2 . 获取SharedPreferences中的数据。

// 1. 获取SharedPreferences对象
SharedPreferences pref = getSharedPreferences("myPref", MODE_PRIVATE);
// 2. 取出数据

String name = pref.getString("name","defaultName");
Intage = pref.getInt("age",0);
Longtime = pref.getLong("time",0);
Booleandefault= pref.getBoolean("default",true);

四. 读写其他应用程序的SharedPreferences数据

要读写其他应用程序的SharedPreferences,前提是该应用程序的SharedPreferences需要指定相应权限,如Context.MODE_WORLD_READABLE(可读,不可写)、Context.MODE_WORLD_WRITABLE(可读写)。

假设要读取的应用程序的的SharedPreferences数据具有Context.MODE_WORLD_WRITABLE权限。为了读取该应用程序的的SharedPreferences,步骤如下:

第一步:创建其他应用程序对应的Context

创建其他应用程序对应的Context的方法如下:

createPackageContext(StringpackageName,intflags)

其中packageName为该应用程序的包名。flag表示该应用程序的安全限制标记。flag的取值如下:

CONTEXT_INCLUDE_CODE:可以执行程序包里的代码;

CONTEXT_IGNORE_SECURITY:忽略安全警告;

CONTEXT_RESTRICTED:严格模式,可能导致一些特殊特性不可用;

示例:

otherAppContext= createPackageContext("cn.edu.sysu.ce.hope", Context.CONTEXT_IGNORE_SECURITY);

第2步:调用其它应用程序的Context的SharedPreferences对象

// 获取SharedPreferences对象SharedPreferences pref = otherAppContext.getSharedPreferences("myPref", MODE_PRIVATE);

第3步:向SharedPreferences对象中读写数据

1 . 读取数据:

String name = pref.getString("name","defaultName");
Intage = pref.getInt("age",0);
Longtime = pref.getLong("time",0);
Booleandefault= pref.getBoolean("default",true);

2 . 写入数据:

// 获取SharedPreferences.Editor对象,用于存储数据修改
SharedPreferences.Editor editor = pref.edit();
// 修改数据信息
editor.putString("name","lisi");
editor.putBoolean("isMale",true);/
/ 提交数据修改
editor.commit();

因为SharedPreferences的数据存储格式就是一个XML文件,所以我们完全可以通过使用I/O流的方式读取该XML文件,再通过XML解析来获取数据。但是显然,这种方式是很繁琐,而是用SharedPreferences读写数据则简单很多。

思路分析

通过上面的介绍相信大家已经对SharedPreferences有了一些了解。接下来让我们思考一下如何存储我们的商品订单信息。

  • 定义一个类将订单所需要的信息封装入类对象。
package com.example.cne_shop.bean;

import java.io.Serializable;

/**
 * Created by 博 on 2017/7/14.
 */

public class ShoppingCart extends Ware implements Serializable {

    private int count ;
    private Boolean isChecked = true ;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public Boolean getChecked() {
        return isChecked;
    }

    public void setChecked(Boolean checked) {
        isChecked = checked;
    }
}

ShoppingCart 继承自类Ware,而类Ware拥有商品的一切信息。代码如下:

package com.example.cne_shop.bean;

import java.io.Serializable;

/**
 * Created by 博 on 2017/7/13.
 */

public class Ware implements Serializable{

    protected long id ;
    protected int categoryId ;
    protected int campaignId ;
    protected String name ;
    protected String imgUrl ;
    protected String price ;
    protected int sale ;

    public int getSale() {
        return sale;
    }

    public void setSale(int sale) {
        this.sale = sale;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

    public int getCampaignId() {
        return campaignId;
    }

    public void setCampaignId(int campaignId) {
        this.campaignId = campaignId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public ShoppingCart toShoppinfCart(){

        ShoppingCart cart = new ShoppingCart() ;

        cart.setId(this.id);
        cart.setCount(1);
        cart.setChecked(true);
        cart.setImgUrl(this.imgUrl);
        cart.setName(this.name);
        cart.setPrice(this.price);

        return cart ;
    }

}

  • 定义一个工具类,供我们使用SharedPreferences,封装其为单例模式,并暴露常用的方法。代码如下:
package com.example.cne_shop.utils;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by 博 on 2017/7/14.
 */

public class PreferenceUtil {

    private static SharedPreferences sharedPreferences = null ;
    private static SharedPreferences.Editor editor = null ;
    private static Context mcontext = null ;
    public static String CAINIAO_SHOPPING = "cainiao_shopping" ;

    private static void GetPreferenceUtil(Context context) {
        mcontext = context ;
        sharedPreferences = context.getSharedPreferences( "Cainiao" , Context.MODE_PRIVATE) ;
        editor = sharedPreferences.edit() ;
    }

    public static void putString(Context context , String key , String value){

        if (mcontext == null || sharedPreferences == null ){
            GetPreferenceUtil(context) ;
        }

        editor.putString(key , value) ;
        editor.commit() ;

    }


    public static String getString(Context context , String key , String defautString){

        if (mcontext == null || sharedPreferences == null ){
            GetPreferenceUtil(context) ;
        }

        return sharedPreferences.getString(key , defautString) ;
    }
}

  • 将我们之前定义的SharedPreferences工具类与ShoppingCart 封装类型结合,封装一个专门存储购物车商品信息的工具类,依然使用单例模式。
  • 数据存储方式,将ShoppingCart 对象转换为json字符串,进行存取,需要时在取出json对象,转化成ShoppingCart 对象。代码如下:
package com.example.cne_shop.utils;

import android.content.Context;
import android.util.Log;
import android.util.SparseArray;

import com.example.cne_shop.bean.ShoppingCart;
import com.example.cne_shop.bean.Ware;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 博 on 2017/7/14.
 */

public class CartProvider {

    private SparseArray<ShoppingCart> datas = null ;
    private Context context = null ;
    private static CartProvider cartProvider ;

    private CartProvider(Context context) {

            this.context = context ;
            this.datas = new SparseArray<>(10) ;
            listToSparseArray() ;

    }

    public static CartProvider getCartProvider(Context context){
        if(cartProvider == null){
            cartProvider = new CartProvider(context) ;
        }
        return cartProvider ;
    }

    public void put (ShoppingCart cart){

        ShoppingCart temp = datas.get((int) cart.getId()) ;
        Log.d("------ ", " "+cart.getId()) ;

        if (temp != null){
            temp.setCount(temp.getCount() + 1);
        }else {
            temp = cart ;
        }

        datas.put((int) cart.getId(), temp);
        conmmit() ;

    }

    public void put (Ware ware){
        ShoppingCart shoppingCart = ware.toShoppinfCart() ;
        this.put(shoppingCart);
    }


    public void update (ShoppingCart cart){
        datas.put((int) cart.getId(), cart);
        conmmit() ;
    }

    public void delete (ShoppingCart cart){
        datas.delete((int) cart.getId());
        conmmit() ;
    }

    public List<ShoppingCart> getAll(){

        return getDataFromlocal() ;
    }

    private List<ShoppingCart>  sparseArrayToList ( ){

        int i = 0 ;
        List<ShoppingCart> carts = new ArrayList<ShoppingCart>();

        for ( i = 0 ; i < datas.size() ; i++){

            carts.add(datas.valueAt(i)) ;
        }

        return carts ;
    }

    private void listToSparseArray(){

        List<ShoppingCart> carts = getDataFromlocal() ;
        if ( carts != null && carts.size() > 0 ){
            for (ShoppingCart cart : carts){
                datas.put((int) cart.getId(), cart);
            }

        }

    }

    private void conmmit(){

        List<ShoppingCart> carts = sparseArrayToList ();

        PreferenceUtil.putString(context ,PreferenceUtil.CAINIAO_SHOPPING , JsonUtil.toJSON(carts));

    }

    public List<ShoppingCart> getDataFromlocal(){

        String json = PreferenceUtil.getString(context ,PreferenceUtil.CAINIAO_SHOPPING , null ) ;
        Log.d("----" , "---"+json) ;
        List<ShoppingCart> carts = new ArrayList<>() ;
        if (json != null && json.length() > 0 ){
            carts = JsonUtil.fromJson(json , new TypeToken<List<ShoppingCart>>(){}.getType()) ;
        }

        return carts ;
    }

}

使用工具

  • 获得对象实例:CartProvider c = CartProvider.getCartProvider(this) ;
  • 存储对象:c.put (ShoppingCart cart)
  • 删除对象:c.delete(ShoppingCart cart)
  • 更新对象信息:c.update (ShoppingCart cart)
  • 获得所有的商品信息:c.getAll()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容