一、Android系统中主要提供了三种方式用于简单的实现数据持久化功能即文件存储、SharePreference存储一级数据库存储。除此之外,还可以将数据保存在手机的SD卡中。
1、文件存储
openFileOutput()方法返回的是一个FileOutputStream对象,用这个对象使用Java流的方式将数据写入文件中
public void save(String inputText)
{
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
OutputStreamWriter构建出一个BufferedWriter对象,这样就可以通过BufferedWriter来将文本内容写到文件中
2、读取数据:与写文件相似,Context中有openFileInput(),用于从文件中读取数据。这个方法的参数就是需要读取的文件名,读取路径也是有系统自动从/data/data/<package name>/files/目录下去加载这个文件,并返回一个FileInputStream。
public String load()
{
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
这里的原理基本与写数据的原理相同
2、SharedPreferences存储
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.commit();
这里是通过getSharePreferences()方法指定SharePreferences的文件名为data,并得到了SharedPreferences.Editor对象。接着向这个对象中添加了三条不同类型的数据,最后调用commit()方法进项提交。 可从文件中找到data.xml文件
5、从SharedPreferences中读取文件。SharedPreferences对象中提供了一系列get方法来进行数据读取
SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean married = pref.getBoolean("married", false);
这里调用了它的getString()、getInt()和getBoolean()方法去获取之前所存储的数据
3、SQLite数据库存储
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
private Context mContext;
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_BOOK);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
这里把建表的语句定义成了字符串常量,然后在onCreate()方法中调用了SQListDatabase的execSQL()方法去执行这条建表语句。
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
dbHelper.getWritableDatabase();
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table Book ("
+ "id integer primary key autoincrement, "
+ "author text, "
+ "price real, "
+ "pages integer, "
+ "name text)";
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code real)";
private Context mContext;
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
如果用以上方法去创建数据库的,Catagory将无法穿件,因为此时BookStore.db数据库已经存在,之后在调用MydatabaseHelper中的onCreate()方法都不再次执行,因此新添加的表也无法得到创建。这里只需要修改onUpgrade()函数
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 开始组装第一条数据
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);
values.clear();
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);
values.clear();
SQListDatabase提供了一个update()方法,它接收四个参数。1:表名、2:ContentValues对象、3,4:用于约束更新某一行或者某一行中的某个数据,不指定的话默认就是更新所有行。
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values , "name = ?", new String[] {"The Da Vinci Code"});
SQListDatabase提供了一个delete()方法,他接收三个参数。1:表名、2,3:用于约束删除某一行或者某几行的数据,不指定的话,默认删除所有行。
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[] {"500"});
这里指明删除Book表中的数据,并且通过第二,第三个参数来指定仅删除那些页数超过500页的书籍。
(4)
SQListDatabase提供了一个query()方法,这个方法的参数非常复杂,最短的也需要七个参数。1:表名、2:指定去查询那几列,如果不指定则默认所有列、3,4:约束查询某一行或者某几行的数据,不指定则默认所有行、5:指定需要去group by的列,不指定则表示不对查询结果进行group bu操作、6:对group bu之后的数据进行进一步的过滤,不指定则表示不进行过滤、7:参数用于指定查询结果排序,不指定则…..
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor.close() = db.query("Book", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
// 遍历Cursor对象,去除数据打印
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
} while(cursor.moveToNext());
}
cursor.close()
这里的query()只使用了第一个参数指明去查询Book表,表示查询表的所有数据。Cursor对象调用moveToFirst()方法将数据的指针移到第一行的位置,然后遍历查询每一行的数据。在通过getColumnIndex()方法获取到某一列在表中对应位置的索引,然后将这个索引传入对应的取值方法中。最后调用close()方法来关闭Cursor。