Android持久化总结(文件存储、SharedPreferences存储、SQLite数据库存储)
Android中针对数据的持久化存储主要提供了3种:文件存储、SharedPreference存储、SQLite数据库存储。除了上面3种外,也可也将数据保存在设备的SD卡中,不过使用这3种相对更简单易用。
文件存储
Android中对文件存储的内容不进行任何格式化处理,所有的数据都是原样保存至文件中,因此比较适合存储一些文本内容或二进制数据。
存储的文件默认都是存储在路径:/data/data/{package_name}/files
这个目录下,{package_name}
为程序的包名。
将数据保存至文件
Context
类中提供openFileOutput()
方法,获取向文件写入数据的输出流。方法需要2个参数:第一个参数是文件名;第二个参数是写入模式,主要有2种(MODE_PRIVATE
、MODE_APPEND
)。MODE_PRIVATE
:是默认的写入模式,该模式下,如果存在同名的时候,会将写入的内容完全覆盖源文件的内容。MODE_APPEND
:如果已存在该文件,就往该文件追加写入数据;如果文件不存在,则新建该文件。
private void save(String content) {
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(content);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null != writer) {
writer.close();
}
if(null != out) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
从文件中读取数据
Context
类中提供openFileInput()
方法,获取从文件读取数据的输入流。
private String load() {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder sbd = new StringBuilder();
try {
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while (null != (line = reader.readLine())) {
sbd.append(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null != reader) {
reader.close();
}
if(null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return sbd.toString();
}
SharedPreferences存储
SharedPreferences
存储是使用键值对的方式来存储数据。
获取SharedPreferences类
Android中主要提供了3中获取SharedPreferences
对应的方式:
Context
类中getSharedPreferences()
方法。
getSharedPreferences()
方法接收2个参数,第一个参数指定文件名称,第二个参数指定操作模式。目前只支持支MODE_PRIVATE
,SharedPreferences
文件都是存放在/data/data/{package_name}/shared_prefs
目录下。Activity
中getSharedPreferences()
方法。
与上面的获取方法类似,不过只接收一个操作模式参数。该方式会自动将当前Activity
类名作为SharedPreferences
的文件名。PreferenceManager
类中的静态方法getDefaultSharedPreferences()
。
getDefaultSharedPreferences()
接收一个Context
参数,并自动使用当前程序的包名作为前缀来命名SharedPreferences
文件。
使用SharedPreferences存储数据
使用SharedPreferences
存储数据主要可以分3个步骤:
- 通过
SharedPreferences
对象的edit()
方法获取SharedPreferences.Editor
对象; - 向
SharedPreferences.Editor
对象中添加数据。如:editor.putString
、editor.putInt
、editor.putBoolean
等; - 调用
SharedPreferences.Editor
对象的apply()
方法,完成数据存储。
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 20);
editor.putBoolean("flag", true);
editor.apply();
从SharedPreferences读取数据
从SharedPreferences
中读取数据,需要先获取SharedPreferences
对象,然后调用一系列get()
方法来获取不同类型的数据。get()
接收2个参数,第一个参数是键值,第二个参数是默认值。
SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean tb = pref.getBoolean("tb", false);
SQLite数据库存储
SQLite
是一款轻量级关系型数据库,运行速度快并且占用资源少,支持标准SQL
语法和数据库的ACID
事务管理。上面的文件存储、SharedPreferences存储对于简单的数据存储很方便,拿来即用,但是需要存储大量的关系数据,就力不从心,这种情况使用SQLite
就再好不过了。
SQLiteOpenHelper
帮助类
为了更方便操作SQLite
,Android专门提供了辅助类SQLiteOpenHelper
。通过SQLiteOpenHelper
可以非常方便的对数据进行创建和更新升级。
SQLiteOpenHelper
抽象类提供了2个抽象方法:onCreate()
和onUpgrade()
。onCreate()
:用于创建数据库;onUpgrade()
:用于更新升级数据库。
SQLiteOpenHelper
中另外还有2个非常重要的方法:getWritableDatabase()
和getReadableDatabase()
。2个方法都能创建或打开数据库,即如果数据库不存在则进行创建并打开,返回一个可对数据库读写操作的对象。区别是,当数据库不可以写入时,getReadableDatabase()
返回的对象将以只读方式打开数据库,getWritableDatabase()
则会抛异常。
见代码:
public class MySQLiteOpenHelper 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,"
+ " `name` TEXT,"
+ " `code` INTEGER)";
private Context mContext;
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Tables Create Success!", Toast.LENGTH_LONG).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);
}
}
使用SQLite
对数据机型增删改查
通过SQLite
辅助类提供的API实现增删改查:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private MySQLiteOpenHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SQLite辅助类对象
dbHelper = new MySQLiteOpenHelper(this, "book.db", null, 1);
/*
* 打开数据库
*/
Button createDatabase = (Button)findViewById(R.id.create_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
/*
* insert 添加数据
*/
Button addData = (Button)findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
for(int i = 1; i <= 100; i ++) {
values.put("author", "Author" + i);
values.put("price", 79);
values.put("pages", 588);
values.put("name", "Name" + i);
db.insert("book", null, values);
values.clear();
}
Toast.makeText(MainActivity.this, "AddData Success", Toast.LENGTH_LONG).show();
}
});
/*
* update 更新数据
*/
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 80);
values.put("pages", 199);
values.put("name", "nnnnnnnnnnn");
db.update("book", values, "id = ?", new String[] {"1"});
Toast.makeText(MainActivity.this, "UpdateData Success", Toast.LENGTH_LONG).show();
}
});
/*
* delete 删除数据
*/
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("book", "id > ?", new String[]{"10"});
Toast.makeText(MainActivity.this, "DeleteData Success", Toast.LENGTH_LONG).show();
}
});
/*
* query 查询数据
*/
Button queryData = (Button)findViewById(R.id.query_data);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("book", null, null, null, null, null, null);
if(cursor.moveToFirst()) {
do {
String author = cursor.getString(cursor.getColumnIndex("author")),
name = cursor.getString(cursor.getColumnIndex("name"));
int id = cursor.getInt(cursor.getColumnIndex("id")),
pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d(TAG, "Id:" + id + "_author:" + author + "_price:" + price + "_pages:" + pages + "_name:" + name);
} while (cursor.moveToNext());
}
cursor.close();
}
});
}
}
处理使用辅助类的API实现对数据库的增删改查外,该辅助类也支持直接使用SQL
语句来操作数据库,主要使用:execSQL()
来实现增、删、改操作;rawQuery()
来实现查操作。
添加数据
db.execSQL("insert into book (`name`, `author`, `pages`, `price`) values (?, ?, ?, ?)", new String [] {"name1", "author1", "800", "132.88"});
更新数据
db.execSQL("update book set `price` = ? where id = ?", new String [] {"99.99", "1"});
删除数据
db.execSQL("delete from `book` where pages > ?", new String [] {"500"});
查询数据
db.rawQuery("select * from book where id > ?", new String [] {"10"});
使用LitePal
操作数据库
LitePal
是Android上的一款ORM
数据库框架。具体可参看项目地址:LitePal。