數(shù)據(jù)持久化就是指將那些內(nèi)存中的瞬時(shí)數(shù)據(jù)保存到存儲(chǔ)設(shè)備中,保證即使在手機(jī)或電腦關(guān)機(jī)的情況下,這些數(shù)據(jù)也不會(huì)丟失。保存在內(nèi)存中的數(shù)據(jù)是處于瞬時(shí)狀態(tài)的,而保存在存儲(chǔ)設(shè)備中的數(shù)據(jù)是處于持久狀態(tài)的,持久化技術(shù)則提供了一種機(jī)制可以讓數(shù)據(jù)在瞬時(shí)狀態(tài)和持久狀態(tài)之間進(jìn)行轉(zhuǎn)換
文件存儲(chǔ)
文件存儲(chǔ)流程:
- 寫:使用openFileOutput("",Context.MODE_PRIVATE)方法返回一個(gè)FileOutputStream,得到此對(duì)象就可以使用Java流的方式將數(shù)據(jù)寫入到文件中了。
- 讀:使用openFileInput("")方法方輝一個(gè)FileInputStream對(duì)象,得到這個(gè)通過Java流的方式就可以將數(shù)據(jù)讀出來了。
public class MainActivity extends AppCompatActivity {
//布局文件很簡單,只需要一個(gè)EditText組件
private EditText edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
//活動(dòng)創(chuàng)建時(shí)從文件中讀取數(shù)據(jù)
String inputText = load();
if (!TextUtils.isEmpty(inputText)){//檢測傳入的字符串是否為null或?yàn)榭兆址? edit.setSelection(inputText.length());//設(shè)置光標(biāo)位于末尾
edit.setText(inputText);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();
//活動(dòng)銷毀時(shí)寫入文件
save(inputText);
}
public void save(String inputText){
FileOutputStream out = null;
BufferedWriter writer = null;
try {
//openFileOutput("data", Context.MODE_PRIVATE)方法第一個(gè)參數(shù)為文件名,第二個(gè)參數(shù)為文件操作模式:MODE_PRIVATE指同名文件覆蓋,MODE_APPEND指同名文件追加。
//所有文件默認(rèn)存儲(chǔ)在這條路徑下/data/data/<package name>/files/data
out = openFileOutput("data", Context.MODE_PRIVATE);
//java流操作
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
}catch (IOException e){
e.printStackTrace();
}finally {
try{
if (writer != null){
writer.close();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
public String load(){
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try{
//openFileInput("data"只有一個(gè)參數(shù)"data",即文件名
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
//reader.readLine()讀取一個(gè)文本行,此方法是按行讀即一行一行的讀
while ((line = reader.readLine())!= null){
content.append(line);
}
}catch (IOException e){
e.printStackTrace();
}
return content.toString();
}
}
SharedPreferences
SharedPreferences存儲(chǔ)流程:
獲取SharedPrecences對(duì)象:
方法一:Context類的getSharedPreferences()
方法二:Activity類的getPreference()
方法三:PreferenceManager類的getDefultSharedPreferences()調(diào)用SharedPreferences對(duì)象的edit()方法來獲取一個(gè)SharedPrefences.Editor對(duì)象
使用putXX()向Editor對(duì)象添加數(shù)據(jù),或用getXX()方法得到數(shù)據(jù)
僅在添加數(shù)據(jù)時(shí),調(diào)用apply()方法將添加的數(shù)據(jù)提交,從而完成數(shù)據(jù)存儲(chǔ)操作
//布局也很簡單,加兩個(gè)按鈕就行了
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private String TAG = "MainActivity";
private Button save_btn;
private Button restore_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
save_btn = (Button) findViewById(R.id.save_btn);
restore_btn = (Button) findViewById(R.id.restore_data);
save_btn.setOnClickListener(this);
restore_btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.save_btn:
//getSharedPreferences("data",MODE_PRIVATE)方法參數(shù):
//"data"為文件名,MODE_PRIVATE為唯一參數(shù)表示只有當(dāng)前應(yīng)用才可以對(duì)這個(gè)SharedPrefences文件進(jìn)行讀寫。
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
editor.putString("name","Tom");
editor.putInt("age",23);
editor.putBoolean("married",false);
editor.apply();
break;
case R.id.restore_data:
SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);
String name = preferences.getString("name","data is bull");
int age = preferences.getInt("age",-1);
boolean married = preferences.getBoolean("married",false);
Log.d(TAG,"name is " + name);
Log.d(TAG, "age is " + age);
Log.d(TAG, "married is " + married);
break;
default:
break;
}
}
}
SQLite數(shù)據(jù)庫存儲(chǔ)
SQLite是Android內(nèi)置的數(shù)據(jù)庫
- 定義一個(gè)SQLiteOpenHelper幫助類(此類的實(shí)例有兩個(gè)方法
getReadableDatabase()、getWritableDatabase()這兩個(gè)方法都可以打開數(shù)據(jù)庫,不同的是當(dāng)數(shù)據(jù)庫不可寫入時(shí),getReadableDatabase()方法返回的對(duì)象將以只讀的方式去打開數(shù)據(jù)庫,而getWritableDatabase()方法則會(huì)出現(xiàn)異常) - 在Activity中實(shí)例化SQLiteOpenHelper對(duì)象
- 調(diào)用
getReadableDatabase()或getWritableDatabase()方法
//定義一個(gè)SQLiteOpenHelper
public class MyDatabaseHelper extends SQLiteOpenHelper{
//SQL語句
public static final String CREATE_BOOK = "create table Book ("
+"id integer primary key autoincrement, "
+"author text, "
+"price real, "
+"pages integer, "
+"name text)";
public String DROP_BOOK = "drop table if exists Book";
public String CREATE_CATEGORY = "create table Category ("
+"id integer primary key autoincrement, "
+"category_name text, "
+"category_code integer)";
public String DROP_CATEGORY = "drop table if exists Category";
private Context mContext;
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//執(zhí)行SQL語句,創(chuàng)建表
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext,"Create succeeded",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//此方法用于更新數(shù)據(jù)庫
//執(zhí)行SQL語句,刪除表
db.execSQL(DROP_BOOK);
db.execSQL(DROP_CATEGORY);
onCreate(db);
}
}
//布局就是添加5個(gè)相應(yīng)的button
public class MainActivity extends AppCompatActivity {
//使用ButterKnife
@BindView(R.id.create_database)
Button createDatabase;
@BindView(R.id.add_data)
Button addData;
@BindView(R.id.updata_data)
Button updataData;
private MyDatabaseHelper databaseHelper;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//實(shí)例化MyDatabaseHelper的三個(gè)參數(shù):
//context;數(shù)據(jù)庫名;允許我們?cè)诓樵償?shù)據(jù)的時(shí)候返回一個(gè)自定義的Cursor,一般都是null;當(dāng)前數(shù)據(jù)庫版本號(hào),可用于對(duì)數(shù)據(jù)庫進(jìn)行升級(jí)
databaseHelper = new MyDatabaseHelper(this,"BookStore.db",null,3);
ButterKnife.bind(this);
}
@OnClick({R.id.create_database,R.id.add_data,R.id.updata_data,R.id.delete_data,R.id.select_data})
public void onClick(View v){
switch (v.getId()){
case R.id.create_database:
databaseHelper.getWritableDatabase();
break;
case R.id.add_data:
SQLiteDatabase db = databaseHelper.getWritableDatabase();
// 使用ContentValues傳入相應(yīng)數(shù)據(jù)
ContentValues values = new ContentValues();
// 開始組裝第一條數(shù)據(jù)
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);//插入第一條數(shù)據(jù)
values.clear();
//開始組裝第二條數(shù)據(jù)
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);//插入第二條數(shù)據(jù)
break;
case R.id.updata_data:
SQLiteDatabase dbUpdata = databaseHelper.getWritableDatabase();
ContentValues valuesUpdata = new ContentValues();
valuesUpdata.put("price",10.99);
dbUpdata.update("Book",valuesUpdata,"name = ?",new String[]{
"The Da Vinci Code"
});
break;
case R.id.delete_data:
SQLiteDatabase dbDelete = databaseHelper.getWritableDatabase();
dbDelete.delete("Book","pages > ?", new String[]{"500"});
break;
case R.id.select_data:
SQLiteDatabase dbSelect = databaseHelper.getWritableDatabase();
//查詢Book表中所有的數(shù)據(jù)
Cursor cursor = dbSelect.query("Book",null,null,null,null,null,null);
if (cursor.moveToFirst()){
do {
//遍歷Cursor對(duì)象,取出數(shù)據(jù)并打印
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"));
Log.d(TAG, "book name is " + name);
Log.d(TAG, "book author is " + author);
Log.d(TAG, "book price is " + price);
}while (cursor.moveToNext());
}
cursor.close();
break;
}
}
}