您的位置:首页 > 移动开发 > Android开发

Android数据持久化

2019-06-05 11:04 113 查看

1、文件存储
文件存储是Android中最基本的一种数据存储方式,他不对存储的内容进行任何格式化处理,所有数据都是原封不动的保存到文件当中,因而它比较适合用于存储一些简单的文本数据或者二进制数据。如果你想使用文件存储的方式保存一些比较复杂的文本数据,就需要定义一套自己的格式规范,这样方便之后将数据从文件中解析出来。
简单一段代码来实现将文本数据存储到文件中:

FileOutputStream out =  null;
BufferedWriter writer = null;
try {
//Context类提供了openFileOutput()方法,用于将数据存储到指定文件中。
//第一个参数表示文件名,这里指定的文件名不能包含路径,因为所有文件默认存储的路径是/data/data/<packageName>/files下的
//第二个参数表示文件的操作模式,MODE_PRIVATE 表示当指定同样文件名的时候,所写入内容会覆盖源文件的内容
//MODE_APPEND 表示如果文件已存在,则往文件中追加内容,如果文件不存在,则新建文件
out = openFileOutput("data",MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write("hello world is happen");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (writer!=null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

存储完成后可以在Andorid Device Monitor工具中进行查看,然后进入到File Explorer 标签页,找到/data/data/packageName/files目录下的data文件,即可进行导出查看保存结果。
用于实现将文件中内容读取出来的简单代码展示:

FileInputStream in = null;
BufferedReader reader = null;
StringBuffer content = new StringBuffer();
try {
//Context类提供的openFileInput()方法,用于从文件中读取数据;
//只有一个参数,表示读取文件的文件名,系统会自动到/data/data/<packageName>/files/目录下去加载这个文件
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));

String line = "";
while((line = reader.readLine())!=null){
content.append(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (reader!=null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return content.toString();

2、SharedPreferences存储
不同于文件存储,SharedPreferences是使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把值取出来。SharedPreferences支持不同的数据类型进行存储。
要想使用SharedPreferences来存储数据,首先需要获取SharedPreferences对象,Android主要提供了三种方法来获取:

  • Conetxt类提供的getSharedPreferences()方法
getSharedPreferences("data",MODE_PRIVATE)

此方法接收两个参数,第一个参数用于指定SharedPreferences文件名,如果指定的文件不存在则会创建一个,SharedPreferences文件都是放在/data/data/package name/shared_prefs/目录下的。
第二个参数用于指定操作模式,目前只有MODE_PRIVATE这一种模式可选,它是默认的操作模式,与直接传入0效果是相同的,表示只有当前的应用程序才可以对这个文件进行读写

  • Activity类中的getPreferences()方法
getPreferences(MODE_PRIVATE)

这个方法只接收操作模式参数,因为使用这个方法会直接将当前活动的类名作为SharedPreferences文件名。

  • PerferenceManager类中的getDefaultSharedPreferences()方法
PreferenceManager.getDefaultSharedPreferences(this);

这里只接收一个Context参数,并使用当前应用程序的包名作为前缀来命名SharedPreferences文件名。
获取到SharedPreferences对象之后,就可以进行存储操作了,主要可以分为3步实现:
(1)调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor的对象;
(2) 向SharedPreferences.Editor对象中添加数据,比如一个布尔型
(3) SharedPreferences.Editor对象调用apply()方法将添加的数据提交,从而完成数据存储。
简单代码如下:

SharedPreferences sp = getSharedPreferences("data",MODE_PRIVATE);
//        SharedPreferences sp = getPreferences(MODE_PRIVATE);
//        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);SharedPreferences.Editor editor = sp.edit();
editor.putString("name","Tony");
editor.putBoolean("sex",true);
editor.apply();

保存成功之后可以借助Android Device Monitor工具中的File Explorer来进行查看,找到/data/data/package name/share_prefs/目录下 data文件,导出查看可以发现 SharedPreferences文件是采用XML格式来进行管理的。

从SharedPreferences文件中读取数据也很简单,就是通过SharedPreferences对象的各种get方法来获取的,这些get方法都接收两个参数,一个是保存时使用的键,一个是默认值,即表示当传入的键找不到对应的值会以默认值的形式返回。简单代码如下

SharedPreferences sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
String name = sharedPreferences.getString("name","");
boolean sex = sharedPreferences.getBoolean("sex",false);
Toast.makeText(this, "name = "+name +"sex = "+sex, Toast.LENGTH_SHORT).show();

3、SQLite数据库存储
SQLite是一种轻量级的关系型数据库,运算速度快,占内存少,通常只需要几百KB,很适合在移动设备上使用。Android系统是内置了数据库的。这里只介绍Android系统内置的。
Android为了让我们能够更加方便的管理数据库,专门提供了SQLiteOpenHelper帮助类,借助这个类可以简单的实现数据库的创建和升级。这个类是抽象类,如果我们要使用它的话,就需要创建一个帮助类去集成它。

**
* SQLiteOpenHelper 提供两个重要的实例方法 getReadableDatabase()和getWritableDatabase()
* 这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库)
* 并返回一个可对数据库进行读写操作的对象。
* 不同的是,当数据库不可写入时(如磁盘空间已满)getReadableDatabase()方法返回的对象只能打开数据库,
* 而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)";
/**
*
* @param context
* @param name  数据库名
* @param factory 允许我们在查询数据的时候返回一个自定义的cursor,一般传为null
* @param version 当前数据库的版本号
*/
public MyDatabaseHelper( Context context,String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
//数据库文件将存在/data/data/<package name>/databases/目录下
}

@Override
public void onCreate(SQLiteDatabase db) {
//创建数据库 调用的方法
//创建Book表
db.execSQL(CREATE_BOOK);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//升级数据库 调用的方法
}
}

用于创建数据库的简单代码:

helper = new MyDatabaseHelper(this,"BookStore.db",null,1);
helper.getReadableDatabase();

升级数据库:
首先创建数据库的版本号更改为2,再在MyDatabaseHelper 中的onUpgrade方法中进行升级数据库:

@Override
public void onCreate(SQLiteDatabase db) {
//创建数据库 调用的方法
//创建Book表
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//升级数据库 调用的方法
//先删除表,再重新创建表
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}

添加数据:

SQLiteDatabase db = helper.getReadableDatabase();
ContentValues values = new ContentValues();
values.put("name","Java in Thinking");
values.put("author","Tony");
values.put("pages",454);
values.put("price",55.67);
//第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值为null
db.insert("Book",null,values);

或者

db.execSQL("insert into Book (name,author,pages,price) values(?,?,?,?)",new String[]{"Java in Thinking","Tony","454","55.67"});

更新数据:

ContentValues values1 = new ContentValues();
values1.put("price",23.78);
db.update("Book",values1,"name = ?",new String[]{"Java in Thinking"});

或者:

db.execSQL("update Book set price = ? where name = ?",new String[]{"23.78","Java in Thinking"});

删除数据:

//第一个参数是表名,第二、第三个参数用于约束删除某一行或某几行的数据,不指定的话默认就是删除所有行
db.delete("Book","pages > ?",new String[]{"500"});

或者:

db.execSQL("delete from Book where pages > ?",new String[]{"500"});

查询数据:

//第一个参数 表名 表示我们希望从哪张表中查询数据
//第二个参数 用于指定去查询哪几列,如果不指定,默认查询所有列
//第三、四个参数 用于约束查询某一行或某几行的数据,不指定则默认查询所有行
//第5个参数 用于指定需要去group by的列,不指定则表示不对查询结果进行group by操作
//第6个参数 用于对group by之后的数据进行进一步的过滤,不指定则不进行过滤
//第7个参数 用于指定对查询结果的排序方式,不指定则表示使用默认的排序方式
Cursor cursor = db.query("Book", null, null, null, null, null, null);
if (cursor.moveToFirst()){
do {
//遍历cursor对象,取出数据
//cursor.getColumnIndex()获取某一列在表中对应的位置索引,再根据这个位置索引获取相应的值
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());
}

或者:

db.rawQuery("select * from Book",null);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: