本項目來自菜鳥窩,有興趣者點擊http://www.cniao5.com/course/
項目已經(jīng)做完,
https://github.com/15829238397/CN5E-shop
仿京東商城系列0------項目簡介
仿京東商城系列1------fragmentTabHost實現(xiàn)底部導(dǎo)航欄
仿京東商城系列2------自定義toolbar
仿京東商城系列3------封裝Okhttp
仿京東商城系列4------輪播廣告條
仿京東商城系列5------商品推薦欄
仿京東商城系列6------下拉刷新上拉加載的商品列表
仿京東商城系列7------商品分類頁面
仿京東商城系列8------自定義的數(shù)量控制器
仿京東商城系列9------購物車數(shù)據(jù)存儲器實現(xiàn)
仿京東商城系列10------添加購物車,管理購物車功能實現(xiàn)
仿京東商城系列11------商品排序功能以及布局切換實現(xiàn)(Tablayout)
仿京東商城系列12------商品詳細信息展示(nativie與html交互)
仿京東商城系列13------商品分享(shareSDK)
仿京東商城系列14------用戶登錄以及app登錄攔截
仿京東長城系列15------用戶注冊,SMSSDK集成
仿京東商城系列16------支付SDK集成
仿京東商城系列17------支付功能實現(xiàn)
仿京東商城系列18------xml文件讀取(地址選擇器)
仿京東商城系列19------九宮格訂單展示
仿京東商城系列20------終章
前言
如果有如果淘寶,或者京東的相信大家都知道,購物車可以存儲用戶的選擇但未付款的訂單。那就說明我們需要一個存儲器來完成這項任務(wù)。由于條件限制,本例采用SharedPreferences進行數(shù)據(jù)存儲。在實際運行中這些信息應(yīng)當在本地和云端同時存貯。但這并不影響本例的研究,我們之研究封裝功能的方法。
基礎(chǔ)了解
在開始研究之前我們先對android為我們提供的數(shù)據(jù)存儲機制,做一簡單的了解。
在Android系統(tǒng)中,主要有五種數(shù)據(jù)存儲模式:
1 .Sharedferences:Sharedferences是一種輕型的數(shù)據(jù)存儲方式,本質(zhì)上是基于XML文件存儲key-value鍵值對數(shù)據(jù)。通常用來存儲一些簡單的配置信息;
2 .File:使用文件進行數(shù)據(jù)存儲;
3 .SQLite:SQLite是一個輕量級的數(shù)據(jù)庫,存儲結(jié)構(gòu)化的數(shù)據(jù),支持基本SQL語法,是常被采用的一種數(shù)據(jù)存儲方式。Android為SQLite提供了一個名為SQLiteDatabase的類,封裝了一些CRUD操作的API;
4 .ContentProvider:ContentProvider為存儲和獲取數(shù)據(jù)提供統(tǒng)一的接口,可以在不同的應(yīng)用程序之間共享數(shù)據(jù);
5 .Network:使用基于網(wǎng)絡(luò)的服務(wù)獲取數(shù)據(jù)。
其中,前四種為本地數(shù)據(jù)持久化的存儲方式。
當應(yīng)用程序只有少量數(shù)據(jù)需要保存,而且這些數(shù)據(jù)的格式很簡單,譬如都是String、Int、Long、Float和Boolean等簡單數(shù)據(jù)類型時,可以使用SharedPreferences來保存,常用于保存應(yīng)用程序的各種配置信息(是否使用振動效果、字體大小等);
當應(yīng)用程序只有少量數(shù)據(jù)需要保存,而且這些數(shù)據(jù)的格式比較復(fù)雜,可以使用普通文件保存;
當應(yīng)用程序有大量數(shù)據(jù)需要存儲和訪問,就可以使用SQLite數(shù)據(jù)庫來保存。SQLite是一個真正輕量級的數(shù)據(jù)庫,它沒有后臺進程,整個數(shù)據(jù)庫就對應(yīng)于一個文件;
當應(yīng)用程序需要引用其他應(yīng)用程序如多媒體播放、通訊錄等的數(shù)據(jù)時,可以使用ContentProvider來調(diào)用數(shù)據(jù)接口;
當應(yīng)用程序需要的數(shù)據(jù)需要跨設(shè)備和持久保存,就不能保存在本地,而應(yīng)該采用網(wǎng)絡(luò)服務(wù)器存儲數(shù)據(jù)。
本文主要講解SharedPreferences的使用與應(yīng)用。
一. SharedPreferences的重要方法
1 . 讀取SharedPreferences數(shù)據(jù)的方法
方法描述
boolean contains (String key)判斷SharedPreferences是否包含特定key的數(shù)據(jù)。
abstract MapgetAll()獲取SharedPreferences數(shù)據(jù)中全部的鍵值對數(shù)據(jù)集合。
abstract Xxx getXxx(String key, Xxx defaultValue)獲取SharedPreferences數(shù)據(jù)里指定key對應(yīng)的value。如果key不存在,則返回defaultValue。其中,Xxx可以是boolean、int、float、long、String。
abstract SetgetStringSet(String key, SetdefValues)獲取SharedPreferences數(shù)據(jù)中指定key對應(yīng)的Set值。
- 向SharedPreferences寫入數(shù)據(jù)的方法
SharedPreferences對象本身只能獲取數(shù)據(jù)而不支持存儲和修改,存儲修改是通過通過SharedPreferences的內(nèi)部接口SharedPreferences.Editor實現(xiàn)的。SharedPreferences調(diào)用edit()方法即可獲取它對應(yīng)的Editor對象。其中Editor對象向SharedPreferences寫入數(shù)據(jù)的方法如下:
方法描述
abstract SharedPreferences.Editor
putXxx(String key, Xxx value)向Editor對象存入指定key對應(yīng)的value數(shù)據(jù)。其中,Xxx可以是boolean、int、float、long、String。
abstract SharedPreferences.Editor
clear()清空Editor對象中的數(shù)據(jù)。
abstract SharedPreferences.Editor
remove(String key)刪除Editor對象中指定的key對應(yīng)的數(shù)據(jù)。
abstract SharedPreferences.Editor
putStringSet(String key, Setvalues)向Editor對象存入指定key對應(yīng)的Set值。
abstract boolean commit()當Editor對象編輯完成后,調(diào)用該方法提交修改。
abstract void apply()提交Editor對象的修改。
二. 向SharedPreferences中存儲數(shù)據(jù)
SharedPreferences本身是一個接口,不能直接創(chuàng)建SharedPreferences實例,可以通過Context提供的getSharedPreferences(String name, int mode)方法來獲取SharedPreferences實例。其中,該方法中的mode參數(shù)可取的值有:
Context.MODE_PRIVATE:指定SharedPreferences數(shù)據(jù)只能被本應(yīng)用程序讀、寫;
Context.MODE_WORLD_READABLE:指定SharedPreferences可被其他應(yīng)用程序讀,但不能寫;
Context.MODE_WORLD_WRITABLE:指定SharedPreferences數(shù)據(jù)可被其他應(yīng)用程序讀、寫。
實現(xiàn)SharedPreferences存儲的步驟如下:
1 . 創(chuàng)建SharedPreferences對象;
2 . 創(chuàng)建SharedPreferences.Editor對象,用于存儲數(shù)據(jù)修改;
3 . 通過Editor對象的putXxx()方法,存儲key-value對數(shù)據(jù)信息;
4 . 通過Editor對象的commit()方法提交對SharedPreferences的修改。
實例如下:
/*
創(chuàng)建SharedPreferences實例
其中"myPref"指SharedPreferences數(shù)據(jù)的XML文件名
指定該SharedPreferences數(shù)據(jù)只能被本應(yīng)用程序讀寫
*/SharedPreferences pref = getSharedPreferences("myPref", MODE_PRIVATE);
// 創(chuàng)建SharedPreferences.Editor對象,用于存儲數(shù)據(jù)修改
SharedPreferences.Editor editor = pref.edit();
// 存儲數(shù)據(jù)信息editor.putString("name","zhangsan");editor.putInt("age",22);
editor.putLong("time", System.currentTimeMillis());editor.putBoolean("default",true);
// 提交數(shù)據(jù)修改editor.commit();
這樣就完成了SharedPreferences的數(shù)據(jù)寫入了。
在Android Studio的DDMS中可以查看"myPref"XML文件信息。myPref.xml所在的文件目錄為 "/data/data/<包名>/shared_prefs/myPref.xml" 。DDMS的打開步驟如下:
"Tools"菜單 ->"Android"菜單 ->"Android Device Monitor"菜單,即可打開DDMS。
在DDMS中查看Android虛擬機下對應(yīng)的"/data/data/<包名>/shared_prefs/myPref.xml",并導(dǎo)出myPref.xml至本地電腦中查看,可看到myPref.xml文件內(nèi)容如下:
zhangsan
三. 讀取本應(yīng)用程序的SharedPreferences
所有創(chuàng)建的SharedPreferences數(shù)據(jù)都可以被本應(yīng)用訪問并進行讀寫操作。
實現(xiàn)SharedPreferences讀取的步驟如下:
1 . 獲取SharedPreferences對象;
2 . 獲取SharedPreferences中的數(shù)據(jù)。
// 1. 獲取SharedPreferences對象
SharedPreferences pref = getSharedPreferences("myPref", MODE_PRIVATE);
// 2. 取出數(shù)據(jù)
String name = pref.getString("name","defaultName");
Intage = pref.getInt("age",0);
Longtime = pref.getLong("time",0);
Booleandefault= pref.getBoolean("default",true);
四. 讀寫其他應(yīng)用程序的SharedPreferences數(shù)據(jù)
要讀寫其他應(yīng)用程序的SharedPreferences,前提是該應(yīng)用程序的SharedPreferences需要指定相應(yīng)權(quán)限,如Context.MODE_WORLD_READABLE(可讀,不可寫)、Context.MODE_WORLD_WRITABLE(可讀寫)。
假設(shè)要讀取的應(yīng)用程序的的SharedPreferences數(shù)據(jù)具有Context.MODE_WORLD_WRITABLE權(quán)限。為了讀取該應(yīng)用程序的的SharedPreferences,步驟如下:
第一步:創(chuàng)建其他應(yīng)用程序?qū)?yīng)的Context
創(chuàng)建其他應(yīng)用程序?qū)?yīng)的Context的方法如下:
createPackageContext(StringpackageName,intflags)
其中packageName為該應(yīng)用程序的包名。flag表示該應(yīng)用程序的安全限制標記。flag的取值如下:
CONTEXT_INCLUDE_CODE:可以執(zhí)行程序包里的代碼;
CONTEXT_IGNORE_SECURITY:忽略安全警告;
CONTEXT_RESTRICTED:嚴格模式,可能導(dǎo)致一些特殊特性不可用;
示例:
otherAppContext= createPackageContext("cn.edu.sysu.ce.hope", Context.CONTEXT_IGNORE_SECURITY);
第2步:調(diào)用其它應(yīng)用程序的Context的SharedPreferences對象
// 獲取SharedPreferences對象SharedPreferences pref = otherAppContext.getSharedPreferences("myPref", MODE_PRIVATE);
第3步:向SharedPreferences對象中讀寫數(shù)據(jù)
1 . 讀取數(shù)據(jù):
String name = pref.getString("name","defaultName");
Intage = pref.getInt("age",0);
Longtime = pref.getLong("time",0);
Booleandefault= pref.getBoolean("default",true);
2 . 寫入數(shù)據(jù):
// 獲取SharedPreferences.Editor對象,用于存儲數(shù)據(jù)修改
SharedPreferences.Editor editor = pref.edit();
// 修改數(shù)據(jù)信息
editor.putString("name","lisi");
editor.putBoolean("isMale",true);/
/ 提交數(shù)據(jù)修改
editor.commit();
因為SharedPreferences的數(shù)據(jù)存儲格式就是一個XML文件,所以我們完全可以通過使用I/O流的方式讀取該XML文件,再通過XML解析來獲取數(shù)據(jù)。但是顯然,這種方式是很繁瑣,而是用SharedPreferences讀寫數(shù)據(jù)則簡單很多。
思路分析
通過上面的介紹相信大家已經(jīng)對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 封裝類型結(jié)合,封裝一個專門存儲購物車商品信息的工具類,依然使用單例模式。
- 數(shù)據(jù)存儲方式,將ShoppingCart 對象轉(zhuǎn)換為json字符串,進行存取,需要時在取出json對象,轉(zhuǎn)化成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()