背景
几乎所有应用都有持久化保存数据的需要。临时性存储savedInstanceState显然无法胜任。为此,Android提供了长期存储地:手机或平板设备闪存上的本地文件系统。
Android设备上的应用都有一个沙盒目录。将文件保存在沙盒中,可阻止其他应用甚至是设备用户的访问和窥探。(当然,如果设备被root了的话,用户就可以为所欲为。)应用的沙盒目录是/data/data/[应用的包名称]。
需要保存大量数据时,大多数应用都不会使用类似txt这样的普通文件。这时候需要使用数据库。SQLite是类似于MySQL和PostgreSQL的开源关系型数据库。不同于其他数据库的是,SQLite使用单个文件存储数据,读写数据时使用SQLite库。Android标准库包含SQLite库以及配套的一些Java辅助类。
示例
基本框架
设计一个用来储存LAB颜色空间的数据类对象。
public class ColorSpace {
private UUID mId;
private String mColorName;
private String mL;
private String mA;
private String mB;
//IDE自动生成的getter和setter,不在展示
//自定义的get和set方法
public String getLABString() {
return getL() + "," + getA() + "," + getB();
}
public int[] getLABInt() {
int[] lab = new int[3];
lab[0] = Integer.parseInt(getL());
lab[1] = Integer.parseInt(getA());
lab[2] = Integer.parseInt(getB());
return lab;
}
public void setLABString(String str) {
String[] ss = str.split(",");
if (ss.length == 3) {
setL(ss[0]);
setA(ss[1]);
setB(ss[2]);
}
}
public void setLABInt(int l, int a, int b) {
setL(String.valueOf(l));
setA(String.valueOf(a));
setB(String.valueOf(b));
}
}
这个数据模型用来储存一个颜色以及它对应的LAB颜色空间的L,A,B通道的值,UUID是保存数据库时用到的一个数据。
一个应用中会用到多个颜色,那么需要设计一个ColorSpaceLab类来管理。
public class ColorSpaceLab {
private static ColorSpaceLab sColorSpaceLab;
private Context mContext;
private SQLiteDatabase mDatabase;
public static ColorSpaceLab get(Context context) {
if (sColorSpaceLab == null) {
sColorSpaceLab = new ColorSpaceLab(context);
}
return sColorSpaceLab;
}
private ColorSpaceLab(Context context) {
mContext = context.getApplicationContext();
mDatabase = BaseHelper.get(context).getReadableDatabase();
}
private ColorSpaceCursorWrapper queryColorSpaces(String whereClause, String[] whereArgs) {
Cursor cursor = mDatabase.query(
ColorSpaceTable.NAME,
null, // Columns - null selects all columns
whereClause,
whereArgs,
null, // groupBy
null, // having
null // orderBy
);
return new ColorSpaceCursorWrapper(cursor);
}
private static ContentValues getContentValues(ColorSpace colorSpace) {
ContentValues values = new ContentValues();
values.put(ColorSpaceTable.Cols.UUID, colorSpace.getId().toString());
values.put(ColorSpaceTable.Cols.COLOR_NAME, colorSpace.getColorName());
values.put(ColorSpaceTable.Cols.L, colorSpace.getL());
values.put(ColorSpaceTable.Cols.A, colorSpace.getA());
values.put(ColorSpaceTable.Cols.B, colorSpace.getB());
return values;
}
public void addColorSpace(ColorSpace c) {
ContentValues values = getContentValues(c);
mDatabase.insert(ColorSpaceTable.NAME, null, values);
}
public void deleteColorSpace(ColorSpace c){
String uuidString = c.getId().toString();
mDatabase.delete(ColorSpaceTable.NAME, ColorSpaceTable.Cols.UUID+"=?",new String[]{ uuidString });
}
public void deleteAllColorSpace(){
List<ColorSpace> colorSpaces= getColorSpaces();
for(int i = 0;i<colorSpaces.size();i++) {
deleteColorSpace(colorSpaces.get(i));
}
}
public List<ColorSpace> getColorSpaces() {
List<ColorSpace> colorSpaces = new ArrayList<>();
ColorSpaceCursorWrapper cursor = queryColorSpaces(null, null);
try {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
colorSpaces.add(cursor.getColorSpace());
cursor.moveToNext();
}
} finally {
cursor.close();
}
return colorSpaces;
}
public ColorSpace getColorSpace(UUID id) {
ColorSpaceCursorWrapper cursor = queryColorSpaces(
ColorSpaceTable.Cols.UUID + " = ?",
new String[] { id.toString() }
);
try {
if (cursor.getCount() == 0) {
return null;
}
cursor.moveToFirst();
return cursor.getColorSpace();
} finally {
cursor.close();
}
}
public void updateColorSpacebyID(ColorSpace colorSpace){
String uuidString = colorSpace.getId().toString();
ContentValues values = getContentValues(colorSpace);
mDatabase.update(ColorSpaceTable.NAME, values,
ColorSpaceTable.Cols.UUID + " = ?",
new String[] { uuidString });
}
public void updateColorSpacebyName(ColorSpace colorSpace){
String name = colorSpace.getColorName();
ContentValues values = getContentValues(colorSpace);
mDatabase.update(ColorSpaceTable.NAME, values,
ColorSpaceTable.Cols.COLOR_NAME + " = ?",
new String[] { name });
}
}
类的中自身的静态变量sColorSpaceLab表明这个类只能被实例化一次,因为一个应用只需要一个颜色管理类。
mContext变量可以保证只要首次创建ColorSpaceLab时的界面每有被销毁,该类就一直存在,不会被自动清理。
SQLiteDatabase类型的mDatabase变量说明该类使用SQLite管理多个颜色空间数据。
在颜色管理类ColorSpaceLab中实现的功能有查询,增加,删除,按UUID和按颜色名称更新。
用到的底层类定义
该类用到了一些更加底层的操作BaseHelper,ColorSpaceCursorWrapper和ColorSpaceTable。
ColorSpaceTable是数据库表格表头的定义
public class ColorSpaceDbSchema {
public static final class ColorSpaceTable {
public static final String NAME = "colorspace";
public static final class Cols {
public static final String UUID = "uuid";
public static final String COLOR_NAME = "color_name";
public static final String L = "l";
public static final String A = "a";
public static final String B = "b";
}
}
}
BaseHelper用来创建数据库
public class BaseHelper extends SQLiteOpenHelper {
private static BaseHelper sBaseHelper;
public static BaseHelper get(Context context) {
if (sBaseHelper == null) {
sBaseHelper = new BaseHelper(context);
}
return sBaseHelper;
}
private static final int VERSION = 1;
private static final String DATABASE_NAME = "templateBase.db";
public BaseHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + ColorSpaceTable.NAME + "(" +
" _id integer primary key autoincrement, " +
ColorSpaceTable.Cols.UUID + ", " +
ColorSpaceTable.Cols.COLOR_NAME + ", " +
ColorSpaceTable.Cols.L + ", " +
ColorSpaceTable.Cols.A + ", " +
ColorSpaceTable.Cols.B +
")"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
当然,在这个数据库中可以新建多张表
ColorSpaceCursorWrapper用来从数据库得到的记录中还原出ColorSpace
public class ColorSpaceCursorWrapper extends CursorWrapper {
public ColorSpaceCursorWrapper(Cursor cursor) {
super(cursor);
}
public ColorSpace getColorSpace() {
String uuidString = getString(getColumnIndex(ColorSpaceTable.Cols.UUID));
String color_name = getString(getColumnIndex(ColorSpaceTable.Cols.COLOR_NAME));
String l = getString(getColumnIndex(ColorSpaceTable.Cols.L));
String a = getString(getColumnIndex(ColorSpaceTable.Cols.A));
String b = getString(getColumnIndex(ColorSpaceTable.Cols.B));
ColorSpace colorSpace = new ColorSpace(UUID.fromString(uuidString));
colorSpace.setColorName(color_name);
colorSpace.setL(l);
colorSpace.setA(a);
colorSpace.setB(b);
return colorSpace;
}
}
有了这些,数据模型的底层就定义完了。
数据模型的使用
在使用时,只需要简单的几行程序就可以实现颜色空间数据的永久保存。
ColorSpaceLab colorSpaceLab = ColorSpaceLab.get(getActivity());
ColorSpace colorSpace = new ColorSpace();
//colorSpace更新
colorSpaceLab.addColorSpace(colorSpace);
colorSpaceLab.updateColorSpacebyName(colorSpace);