- Android的数据存储方式有:SharedPreferences,File,SQLite,下面来详细介绍每种数据存储的特点与使用;
SharedPreferences
-
SharedPreferences
是Android平台上一个轻量级的数据存储辅助类,用来保存应用的一些常用配置,它提供了string,set,int,long,float,boolean六种数据类型,最终数据是以xml形式进行存储,在应用中通常做一些简单数据的持久化缓存
;
SharedPreferences的使用注意事项:
-
不要存放大的key和value
在SharedPreferences中,否则会一直存储在内存中得不到释放
,内存使用过高会频发引发GC,导致界面丢帧甚至ANR;
- 不相关的配置选项最好不要放在一起,单个文件越大读取速度则越慢;
- 读取频繁的key和不频繁的key尽量不要放在一起(如果整个文件本身就较小则忽略,为了这点性能添加维护得不偿失);
-
不要每次都edit
,因为每次都会创建一个新的EditorImpl对象,最好是批量处理统一提交
,否则edit().commit每次创建一个EditorImpl对象并且进行一次IO操作,严重影响性能;
-
commit发生在UI线程中
,apply发生在工作线程中
,对于数据的提交最好是批量操作统一提交
,虽然apply发生在工作线程(不会因为IO阻塞UI线程)但是如果添加任务较多也有可能带来其他严重后果(参照ActivityThread源码中handleStopActivity方法实现)
-
尽量不要存放json和html
,这种可以直接文件缓存;
-
SharedPreferences不能跨进程通信 Context.PROCESS
;
-
最好提前初始化SharedPreferences
,避免第一次创建时读取文件线程未结束而出现等待情况;
SharedPreferences的创建
- 创建SharedPreferences有两种方式:
- 第一种:调用Context对象的getSharedPreferences()方法;
- 第二种:调用Activity对象的getPreferences()方法;
- 区别在于:第一种方式获得的可以被
同一应用程序下的组件共用
,但是第二种方式获得的只可以在该Activity下使用
;
SharedPreferences的操作模式
-
MODE_PRIVATE
:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下写入的内容会覆盖原文件的内容;
-
MODE_APPEND
:检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
-
MODE_WORLD_READABLE
:表示当前文件可以被其他应用读取;
-
MODE_WORLD_WRITEABLE
:表示当前文件可以被其他应用写入;
SharedPreferences的增删改查
- 封装成单例类
SFSharedPreferences
,代码实现如下:
package com.example.yyshop.general.database;
import android.content.Context;
import android.content.SharedPreferences;
import static android.content.Context.MODE_PRIVATE;
public class SFSharedPreferences {
private static volatile SFSharedPreferences mInstance;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public static synchronized SFSharedPreferences getInstance(Context context){
if (mInstance == null) {
synchronized (SFSharedPreferences.class) {
if (mInstance == null) {
mInstance = new SFSharedPreferences(context);
}
}
}
return mInstance;
}
private SFSharedPreferences(Context context){
if (sharedPreferences == null) {
//创建SharedPreferences实例对象
sharedPreferences = context.getSharedPreferences("config",MODE_PRIVATE);
editor = sharedPreferences.edit();
}
}
//存储数据
public void save(String key,String data) {
editor.putString(key,data);
editor.commit();
}
//读取数据
public String read(String key){
String data = sharedPreferences.getString(key,"");
return data;
}
//删除数据
public void remove(String key) {
editor.remove(key);
editor.commit();
}
//清空所有数据
public void clear() {
editor.clear();
editor.commit();
}
}
- 注意⚠️:SharedPreferences在
存储,删除,清空
数据时,都是通过editor
对象进行操作的,且必须调用editor.commit()
,进行提交操作才能生效;
- 外界调用代码如下:
public class SFShopCarFragment extends SFBaseFragment {
@Override
protected void initUI() {
Button button = find(R.id.shopcar_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), SFShopDetailActivity.class);
startActivity(intent);
SFSharedPreferences.getInstance(getContext()).save("name","yanzi");
String name = SFSharedPreferences.getInstance(getActivity()).read("name");
Log.i("SFShopCarFragment",name);
}
});
}
@Override
protected int getLayoutId() {
return R.layout.fragment_shopcar;
}
}
- SharedPreferences存储数据的位置为:
/data/data/项目包/shared_prefs/名称.xml
,可通过Device File Explore
进行查看,如下所示:
image.png
SQLite数据库
- SQLite是一款轻量型数据库,广泛使用于移动端;
- 在Android中,系统封装了一个SQLite数据库的抽象类
SQLiteOpenHelper
,我们需要自定义一个子类
继承自抽象类SQLiteOpenHelper
,实现其相关的抽象方法,然后进行数据库的增删改查操作;
抽象类SQLiteOpenHelper
的两个抽象方法
- 第一个抽象方法是:onCreate方法,在实例化继承自SQLiteOpenHelper的子类时调用(创建数据库时),在这个方法中我们可进行
数据库表的创建
,此方法只会调用一次;
- 第二个抽象方法是:onUpgrade方法,在数据库升级时使用;
- 有关数据库的增删改查操作,见如下代码:
package com.example.yyshop.general.database;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.example.yyshop.home.model.SFGoodModel;
import java.util.ArrayList;
import java.util.List;
public class SFSQLShopCarHelper extends SQLiteOpenHelper {
//数据库版本号
private static Integer Version = 1;
//数据库的名称
private static final String DATA_BASE_NAME = "shopcar.db";
//购物车商品表
private static final String SHOP_CAR_TABLE_NAME = "t_goods";
//单例对象
private static volatile SFSQLShopCarHelper mInstance;
//在SQLiteOpenHelper的子类当中,必须有该构造函数
private SFSQLShopCarHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
//必须通过super调用父类当中的构造函数
super(context, name, factory, version);
}
private SFSQLShopCarHelper(Context context, String name, int version) {
this(context,name,null,version);
}
private SFSQLShopCarHelper(Context context, String name) {
this(context, name, Version);
}
private SFSQLShopCarHelper(Context context) {
this(context,DATA_BASE_NAME);
}
public static synchronized SFSQLShopCarHelper getInstance(Context context) {
if (mInstance == null) {
synchronized (SFSharedPreferences.class) {
if (mInstance == null) {
mInstance = new SFSQLShopCarHelper(context);
}
}
}
return mInstance;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.i("SFSQLShopCarHelper","开始创建数据库表 t_shopCar");
createTable(db);
Log.i("SFSQLShopCarHelper","完成创建数据库表 t_shopCar");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//数据库升级
}
//创建表
private void createTable(SQLiteDatabase database){
String create_shop_car_goods = "create table if not exists " + SHOP_CAR_TABLE_NAME +"(id integer primary key autoincrement,goodId text,goodName text,goodPic text,goodPrice text)";
try {
database.execSQL(create_shop_car_goods);
} catch (Exception e) {
e.printStackTrace();
Log.i("SFSQLShopCarHelper", "创表shop_car_goods -- 出现异常");
};
}
//插入单条数据
public void insert(SFGoodModel model){
SQLiteDatabase database = getWritableDatabase();
String goodId = model.getGoodsId();
String goodName = model.getGoodsName();
String goodPic = model.getComPic();
String goodPrice = model.getPrice();
String insert = "insert into " + SHOP_CAR_TABLE_NAME + "(goodId,goodName,goodPic,goodPrice)values" + "('"+goodId+"','"+goodName+"','"+goodPic+"','"+goodPrice+"')";
database.execSQL(insert);
Log.i("SFShopCarFragment",insert);
Log.i("SFShopCarFragment","插入了1条数据");
database.close();
}
//查询所有商品
public List<SFGoodModel> select(){
SQLiteDatabase database = getReadableDatabase();
List<SFGoodModel> models = new ArrayList<>();
String select = "select * from " + SHOP_CAR_TABLE_NAME;
Cursor cursor = database.rawQuery(select,null);
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex("id"));
String goodName = cursor.getString(cursor.getColumnIndex("goodName"));
String goodId = cursor.getString(cursor.getColumnIndex("goodId"));
String goodPic = cursor.getString(cursor.getColumnIndex("goodPic"));
String goodPrice = cursor.getString(cursor.getColumnIndex("goodPrice"));
SFGoodModel model = new SFGoodModel();
model.setGoodsId(goodId);
model.setGoodsName(goodName);
model.setGoodsId(goodPic);
model.setGoodsId(goodPrice);
models.add(model);
Log.i("SFShopCarFragment", id + " " + goodName + " " + goodId + " " + goodPic + " " + goodPrice);
}
//关闭数据库
cursor.close();
database.close();
return models;
}
//删除指定商品
public void delete(SFGoodModel model) {
SQLiteDatabase database = getReadableDatabase();
String delete = "delete from " + SHOP_CAR_TABLE_NAME + " where goodid = '"+model.getGoodsId()+"'";
try {
database.execSQL(delete);
Log.i("SFSQLShopCarHelper","成功删除一条数据");
database.close();
} catch (Exception e) {
e.printStackTrace();
Log.i("SFSQLShopCarHelper", "删除指定数据 -- 出现异常");
database.close();
}
}
//删除所有商品
public void deleteAll(){
SQLiteDatabase database = getReadableDatabase();
String delete = "delete from " + SHOP_CAR_TABLE_NAME;
try {
database.execSQL(delete);
Log.i("SFSQLShopCarHelper","成功删除所有数据");
database.close();
} catch (Exception e) {
e.printStackTrace();
Log.i("SFSQLShopCarHelper", "删除所有数据 -- 出现异常");
database.close();
}
}
}
- 上述自定义子类
SFSQLShopCarHelper
继承自SQLiteOpenHelper
系统抽象类;
- 在进行数据库的增删改查时,首先是获取database,调用
getReadableDatabase()
或者getWritableDatabase()
方法,相当于打开数据库,在执行完数据库的增删改查操作之后,调用close()
方法,关闭数据库;
网友评论