Android 系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储、SharedPreference 存储以及数据库存储。除了这三种方式之外,你还可以将数据保存在手机的 SD 卡中,不过使用文件、SharedPreference或数据库来保存数据会相对更简单一些,而且比起将数据保存在 SD 卡中会更加的安全。
1文件存储
文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据.
1.1 将数据存储到文件中
Context 类中提供了一个 openFileOutput (arg1,arg2)方法.
arg1, 文件名,在文件创建时使用到这个名称。不可以包含路径。
arg2,文件的操作模式。主要有两种模式可选,MODE_PRIVATE 和 MODE_APPEND.
MODE_PRIVATE是默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件的内容
MODE_APPEND则表示如果文件已存在就往文件里面追加内容,不存在就创建新文件。
openFileOutput ()方法返回的是一个 FileOutputStream 对象,得到了这个对象之后就可以使用 Java 流的方式将数据写入到文件中了。所有文件都默认存储在到 %ANR_ADB%/data/<package name>/files目录下。
package qhy.store;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText edit ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
String inputText = load();
if( !TextUtils.isEmpty( inputText ) ){
edit.setText( inputText );
edit.setSelection( inputText.length() );
Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_LONG).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String input = edit.getText().toString();
save(input);
}
public void save(String input) {
try(FileOutputStream out = openFileOutput("data", Context.MODE_PRIVATE) ;
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)) ;
){
writer.write(input);
Log.d("ok", "success");
} catch (IOException e) {
e.printStackTrace();
}
}
public String load(){
StringBuilder content = new StringBuilder();
try(FileInputStream in = openFileInput("data");
BufferedReader 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();
};
return content.toString();
}
}
在activity_main.xml中的代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<EditText android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_string"/>
</LinearLayout>
在strings.xml中的代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">文件存储</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="hint_string">Type something here</string>
</resources>
2 SharePreferences存储
2.1 得到SharedPreferences 对象的3种方式
要想使用SharedPreferences来存储数据, 首先需要获取到SharedPreferences对象。 Android中主要提供了三种方法用于得到 SharedPreferences 对象。
1、Context类中的getSharedPreferences(arg1 , arg2)方法
arg1 : SharedPreferences文件的名称,如果指定文件不存在则会创建一个,SharedPreferences文件都是存放在/data/data/<package_name>/shared_prefs/目录下的。
arg2:操作模式,主要有两种操作模式,MODE_PRIVATE和MODE_MULT_PROCESS.
MODE_PRIVATE 默认操作模式,和直接传入0效果相同,表示只有当前应用程序才可以对这个
SharedPreferences文件进行读写的情况。
MODE_MULTI_PROCESS:一般是用于会有多个进程中对同一个SharedPreferences文件进行读写的情况。
2、Activity 类中getPreferences( arg )方法
arg : 操作模式参数, SharedPreferences 的文件名:当前活动的类名.
3、PreferenceManager 类中的 getDefaultSharedPreferences()方法
这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作
为前缀来命名 SharedPreferences 文件。
2.2 SharedPreferences存储数据的步骤
1、 调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
2、向 SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用
putBoolean 方法,添加一个字符串则使用 putString()方法,以此类推。
3、调用 commit()方法将添加的数据提交,从而完成数据存储操作。
3 SQLite 数据库存储
SQLite是一款轻量级的关系数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够呢,特别适合在移动设备上使用。SQLite不仅支持标准的SQL语法,还遵循了数据库的ACID事务。SQLite比一般的数据库简单得多,可以不用设置用户名和密码就能使用。
ACID:指数据库事务正确执行的四个基本要素的首字母缩写。
-
原子性(Atomicity):确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。
-
一致性(Consistency):确保数据库在成功提交的事务上正确地改变状态。
-
隔离性(Isolation):使事务操作相互独立和透明。
-
持久性(Durability):确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。
3.1 创建数据库
Android为了让我们能够更加方便地管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。
SQLiteOpenHelper是一个抽象类,有两个抽象方法onCreate与onUpgrade().分别实现创建、升级数据库的逻辑。
SQLiteOpenHelper中有两个非常重要的实例方法,getReadableDatabase() 和 getWritableDatabase() 。 这两个方法都可以创建或打开一个现有的数据库,并返回一个队数据库进行读写操作的对象。当数据库不可写入时(如磁盘空间已满)getReadableDatabase()方法返回的对象将以只读的方式打开数据库,而getWritableDatabase()方法将出现异常。
数据库文件会存放在:/data/data/<package name>/databases/ 目录下 , 只能看见数据库文件。为看见数据库下面的表结构,需要把Android SDK下的platform-tools放到环境变量中。
SQLite 的数据类型:integer 表示整型,real表示浮点型,text表示文本型,blob表示二进制类型。autoincrement表示自增长。
新增数据:
SQLiteDatabase db = dbHelper.getWritableDatabase();//dbHelper是SQLiteOpenHelper的子类
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 Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.95);
db.insert("Book", null, values); //
db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99","The Da Vinci Code" });
更新数据:
SQLiteDatabase db = dbHelper.getWritableDatabase();
//arg1: 表名; arg2:sql语句中where后的条件; arg3:其后的条件
db.delete("Book", "pages > ?", new String[] { "500" });
db.execSQL("delete from Book where pages > ?", new String[] { "500" });
查询数据:
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("book", null, null, null, null, null, null);
if( cursor.moveToFirst() ){
do{
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();
db.rawQuery("select * from Book", null);