Android学习笔记(六)数据持久化

本文详细介绍了Android中的数据存储方式,包括文件存储、SharedPreferences存储及SQLite数据库存储。涵盖了各种存储方式的特点、应用场景及具体实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6.1 持久化简介

        Android 系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储SharedPreference 存储以及数据库存储
        当然,除了这三种方式之外,你还可以将数据保存在手机的 SD 卡中,不过使用文件、SharedPreference或数据库来保存数据会相对更简单一些,而且比起将数据保存在 SD 卡中会更加的安全。

6.2 文件存储

        文件存储是 Android 中最基本的一种数据存储方式,它不对数据进行任何格式化处理,原封不动保存。适用于存储一些简单的文本数据或二进制数据。

6.2.1 存储数据

Context类提供了一个openFileOutput()方法,用于将数据存储到指定文件中。
try {
    /**
     * 1.通过openFileOutput()方法来获得FileOutputStream流,然后通过此流去写入数据
     * 2.param1:文件名,不可以包含路径,因为所以文件默认都存储在/data/data/<packagename>/files/目录下
     * 3.param2:操作模式,主要有两种:MODE_PRIVATE、MODE_APPEND
     * MODE_PRIVATE——默认模式,指定文件名相同时,写入内容将覆盖原有内容
     * MODE_APPEND——追加模式,如果该文件已存在,则追加内容;否则创建文件
     * ps:还有两种MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE因为容易被其他应用程序操作而在Android 4.2中废弃。
     */
    FileOutputStream fileOutputStream = openFileOutput("fileName", Context.MODE_APPEND);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

6.2.2 读取数据

类似于存储,Context类提供了一个openFileinput()方法,用于从文件中读取数据,接收要读取的文件名作为参数。

6.3 SharedPreferences存储

使用键值对的方式来存储数据,并且支持多种不同的数据类型存储,存的为整型,则读取的也为整型;存的为字符串,则读取的也是字符串。

6.3.1 存储数据

1. 首先需要获取到SharedPreferences对象,Android中提供了三种方式:
(1)Context 类中的 getSharedPreferences()方法
/**
 * param1:指定文件名称,如果不存在则会创建一个,SharedPreferences文件都是存放在/data/data/<packagename>/shared_prefs/目录下的
 * param2:操作模式,MODE_PRIVATE和MODE_MULTI_PROCESS
 * MODE_PRIVATE——默认操作模式,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写,和0效果相同。
 * MODE_MULTI_PROCESS——用于会有多个进程对同一个文件进行读写的情况
 * MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE 这两种模式已在 Android 4.2 版本中被废弃
 */
SharedPreferences sharedPreferences = getSharedPreferences("fileName", Context.MODE_PRIVATE);
(2)Activity 类中的 getPreferences()方法
/**
 * 使用此方法会自动将当前的活动类名作为SharedPreferences的文件名
 * param:模式
 */
SharedPreferences sharedPreferences1 = this.getPreferences(Context.MODE_PRIVATE);
(3)PreferenceManager 类中的 getDefaultSharedPreferences()方法
/**
 * 静态方法,自动使用当前程序的包名作为前缀来命名SharedPreferences文件
 * param:Context上下文
 */
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
2.调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
SharedPreferences.Editor editor=sharedPreferences.edit();
3.向 SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用putBoolean 方法,添加一个字符串则使用 putString()方法,以此类推。
editor.putString("name", "Jastar");
editor.putInt("age", 26);
editor.putBoolean("married",false);
4.调用 commit()方法将添加的数据提交
editor.commit();

6.3.2 读取数据

通过SharedPreferences对象的一系列getXXX()方法,第一个参数为键值,第二个为默认值,即当传入的键找不到对应的值时则使用此值。

6.4 SQLLite数据存储


  • SQLite 是一款轻量级的关系型数据库,运算速度非常快,占用资源少,通常只需要几百k的内存;
  • 不仅支持标准的sql语法,还遵循数据库的ACID事务;
  • 数据库文件会存放在/data/data/<packagename>/databases/目录下。
  • 数据库类型:integer(整型)、real(浮点型)、text(文本类型)、blob(二进制类型)

6.4.1 SQLiteOpenHelper帮助类

为了方便管理数据库,Android专门提供了此帮助类。SQLiteOpenHelper是一个抽象类,使用时需要创建自己的类去继承。

(1)需重写以下两个方法:
onCreate(SQLiteDatabase db):创建数据库完成后调用该方法
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion):升级数据库完成后调用该方法
(2)有两个构造函数可以重写,但一般重写参数较少的就可以:
/**
 * @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);
}
(3)有两个非常重要的实例方法:
 相同点不同点
getReadableDatabase()都可以创建或打开一个现有的数据库(存在则打开,否则创建)
并返回一个可对数据库进行读写操作的对象
当数据库不可写入时(如磁盘已满),该方法返回对象将以只读方式打开数据库
getWritableDatabase()当数据库不可写入时,出现异常

6.4.2 创建数据库

(1)创建数据库
MyDatabaseHelper helper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
helper.getWritableDatabase();
(2)创建数据表
建表一般在onCreate()方法中编写,这样当数据库创建完成时便会自动创建表,通过该方法的参数来执行:
@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("sql语句");
}
(3)使用adb shell来查看已创建的表
adb 是 Android SDK 中自带的调试工具,使用它可以直接对连接在电脑上的手机或模拟器进行调试操作。

a>它存放在 sdk 的 platform-tools 目录下,如果想要在命令行中使用这个工具,就需要先把它的路径配置到环境变量里。
b>打开dos命令界面,输入adb shell,就会进入到设备控制台:



c>使用 cd 命令进入到/data/data/<packagename>/databases/目录下:


d>使用 ls 命令查看该目录下的文件



BookStore.db:创建的数据库
BookStore.db-journal:为了让数据库能够支持事务而产生的临时日志文件,通常该文件大小都为0字节。

e>使用 sqlite3 命令来打开数据库:


f>输入 .table 命令查看目前有哪些表


android_metadata:数据库创建时自动生成的,不用管。

g>输入 .schema 命令查看它们的建表语句


h> 输入 .exit 或 .quit 命令来退出数据编辑,再输入 exit(注意无点)命令即可退出设备控制台。


6.4.3 升级数据库

如果此时需求想添加其他的表,则在onCreate()方法中代码将会不起作用,因为数据库已经存在了,所以不会再执行onCreate()方法。
(1)创建SQLiteOpenHelper类实例时修改数据库版本号:
//只要版本号比创建的时候高就可以
MyDatabaseHelper helper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
helper.getWritableDatabase();
(2)数据库版本更新完成之后便会执行onUpgrade()方法:
@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("建Book表的sql");
    db.execSQL("建Category表的sql");
    Toast.makeText(myContext, "表Book创建成功!", Toast.LENGTH_SHORT).show();
}

@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);
}

6.4.4 CRUD操作

(1)添加
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);
/**
 * 插入数据
 * param1:表名
 * param2:用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般用不到,传入null即可
 * param3:一个ContentValues对象,提供了一系列put()方法,只需要把表的列名和数据添加进去即可
 */
db.insert("Book", null, values);
//当有多条数据添加时,该对象也可复用,不过要记得clear一下
values.clear();
(2)更新
SQLiteDatabase db = dbHelper.getWritableDatabase();
//想更新哪一列就添加哪一列的数据
ContentValues values = new ContentValues();
values.put("price", 9.9);
/**
 * 更新操作
 * param1:表名
 * param2:要更新的数据
 * param3&4:用于约束更新某一行或几行的条件,不指定的话则默认更新所有行。
 * ?为占位符
 */
db.update("Book", values, "name=?", new String[]{"The Da Vinci Code"});

(3)删除
通过delete()方法,类似以上用法
(4)查询
SQLiteDatabase db = dbHelper.getWritableDatabase();
/**
 * 查询方法参数最少的重载就有7个
 * param1:表名
 * param2:查询哪几列(不指定则所有)
 * param3:类似于where条件(如id=?)
 * param4:类似于where条件参数(如new String[]{"1"})
 * param5:group by的列(不指定则所有)
 * param6:group by后进一步过滤的列(having)
 * param7:排序
 */
Cursor cursor = db.query("Book", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
    do {
        String name = cursor.getString(cursor.getColumnIndex("name"));
        //....
    } while (cursor.moveToNext());
}
//关闭
cursor.close();


6.4.5 使用sql操作数据库

(1)插入
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" });
db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" });
(2)更新
db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99","The Da Vinci Code" });
(3)删除
db.execSQL("delete from Book where pages > ?", new String[] { "500" });
(4)查询
db.rawQuery("select * from Book", null);

6.4.6 使用事务

SQLiteDatabase db = dbHelper.getWritableDatabase();
//开启事务
db.beginTransaction();
try {
    //一系列操作
    //...
    //事务成功
    db.setTransactionSuccessful();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    //结束事务
    db.endTransaction();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值