Android - 数据的存储
Contents
Android中的数据存储有以下几种方式:
- 文件存储
- SharedPreferences
- SQLite数据库
- Content Provider
文件存储
Activity中的openFileOutput()
方法可以用于把数据输出到文件中,具体的实现过程与在JavaSE 环境中保存数据到文件中是一样的。openFileInput()
方法则用于读取当前应用的保存的数据
openFileOutpupt详解
openFileOutput(String name, int mode)
name - 指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。创建的文件保存在/data/data/
mode - 文件操作模式,即访问权限
0 或者MODE_PRIVATE 默认的模式,文件为私有的,只能本应用程序才能访问;
MODE_APPEND 添加默认,数据将追加到文件末尾;
MODE_WORLD_READABLE 全局可读;!危险
MODE_WORLD_WRITEABLE 全局可写。!危险
eg.
1 | public class FileActivity extends Activity { |
获得应用的文件存储路径
getFileDir()
- /data/data/<当前应用包名>/files/getCacheDir()
- /data/data/<当前应用包名>/cache/Environment.getExternalStorageDirectory()
- 用于获取SDCard的目录,
注意:
- 写数据应在程序清单文件中加入sdcard的访问权限:
android.permission.WRITE_EXTERNAL_STORAGE - 先判断sdcard是否挂载:
Environment.getExternalStorageState() 应返回 Environment.MEDIA_MOUNTED
eg.获取sdcard的可用大小:1
2
3
4
5
6
7
8if(Environment.getExternalStorageState().equals(Environment. MEDIA_MOUNTED)){
File sd = Environment. getExternalStorageDirectory();
StatFs stat = new StatFs(sd.getPath());
long availableBlocks = stat.getAvailableBlocks();
long blockSize = stat.getBlockSize();
long availableSize = availableBlocks * blockSize;
String totalAvailableSize = Formatter.formatFileSize(getApplicationContext(), availableSize);
}SharedPreferences
Android应用一般采用SharedPreferences来存储于应用相关的配置参数
其实就是/data/data/<package name>/shared_prefs/
目录下的xml文件存数据
SharedPreferences存数据需要调用edit()
来获得Editor对象,调用其putXxx()
方法来设置key及对应的值,赋值结束后需调用commit()
方法来提交更改
eg.生成的config.xml文件1
2
3
4
5
6
7String data = "test";
// 指定文件名,及其访问模式
SharedPreferences sp = context.getSharedPreferences("config", MODE_PRIVATE);
Editor edit = sp .edit();
edit.putString( "data", data);
edit.putInt( "num", 123);
edit.commit();SharedPreferences - config.xml 1
2
3
4
5<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="data">test</string>
<int name="num" value="123" />
</map>读数据
getXxx(key,defaultValue)
Xxx为数据类型。
如果对应key在SharedPreferences没有数据则会返回defaultValue
eg.1
2
3SharedPreferences sp = context.getSharedPreferences("config", MODE_PRIVATE );
String data = sp.getString("data","abc");// 若没有读取到key为data对应的值,则返回abc
int num = sp.getInt("num",111);// 若没有读取到key为num对应的值,则返回111SQLite数据库
Android底层内嵌了数据库SQLite。
Android sdk提供了SQLiteOpenHelper
抽象类,来进行数据库的版本控制。
Android下创建数据库的步骤:
- 创建一个数据库打开的帮助类,继承SQLiteOpenHelper
- 构造方法中的参数:设置数据库文件的名称,设置游标工厂(一般为null),数据库的版本
- 覆盖
onCreate()
方法:数据库表结构的初始化,数据库第一次被创建的时候会调用的方法 helper.getReadabledatabase()
或者调用helper.getWriteabledatabase()
获取数据库的示例
SQLiteOpenHelper
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)
和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
,
前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。
当调用SQLiteOpenHelper对象的getWritableDatabase()
或者getReadableDatabase()
方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()
方法。
onCreate()
方法在初次生成数据库时才会被调用,在onCreate()
方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()
方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的
WritableDatabase和ReadableDatabase
getWritableDatabase()
和getReadableDatabase()
方法都可以获取一个用于操作数据库的SQLiteDatabase实例。
但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。
getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
第一次调用getWritableDatabase()或getReadableDatabase()方法后,SQLiteOpenHelper会缓存当前的SQLiteDatabase实例,SQLiteDatabase实例正常情况下会维持数据库的打开状态,所以在当不再需要SQLiteDatabase实例时,应及时调用close()
方法释放资源。
一旦SQLiteDatabase实例被缓存,多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例
SQLite事务
使用SQLiteDatabase的beginTransaction()
方法可以开启一个事务,程序执行到endTransaction()
方法时会检查事务的成功标识是否为true,如果程序执行到endTransaction()
之前调用了setTransactionSuccessful()
方法设置事务的标识为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。
eg.
1 | public class NoteSQLiteOpenhelper extends SQLiteOpenHelper { |
1 | public class NoteDao { |
SQLite3命令
可以利用adb工具进入到Android的linux控制台,通过sqlite3 命令进行数据库的操作(一般需要有root权限,Android虚拟机默认为root)。
$ adb shell 首先挂载到linux
$ cd data/data/com.android.contacts.provider
$ cd databases
$ sqlite3 <数据库> 打开数据库:sqlite3 contacts.db
sqlite3>.tables 查看所有的表
sqlite3>.schema 查看所有的创建表、视图
sqlite3>.help 查看帮助
sqlite3>.header(s) NO |OFF是否显示列头信息
sqlite3>.mode MODE table 指定数据显示风格 eg: .mode column
sqlite3>.nullValue NULL空值数据显示问题 eg: .nullValue NULL
内容提供者content provider
应用的数据一般是私有的,外部是不可以访问的,可以通过content provider来对外提供私有数据的访问,如增删改查。
*具体见ContentProvider的详解篇
Author: Yrom
Link: https://yrom.net/blog/2011/12/20/android-storage/
License: 知识共享署名-非商业性使用 4.0 国际许可协议