任何一個應用程序,其實說白了就是在不停地和數據打交道,聊QQ、看新聞、刷微博,所關心的都是裏面的數據,沒有數據的應用程序就變成了一個空殼子,對用戶來說沒有任何實際用途。大多數的數據基本都是由用戶產生的,比如發微博、評論新聞,其實都是在產生數據。
而對於之前博文中我們用到的各種各樣的數據,都是瞬時數據。所謂的瞬時數據則是有可能會因爲程序關閉或其他原因導致內存被回收而丟失的數據。對於一些關鍵性的信息而言,這是不可以的。而保證關鍵性的數據不丟失的技術則是數據持久化技術了。
數據持久化就是指將那些內存中的瞬時數據保存到存儲設備中,保證即使在手機或電腦關機的情況下,這些數據仍然不會丟失。保存在內存中的數據是處於瞬時狀態的,而保存在存儲設備中的數據是處於持久狀態的,持久化技術則提供了一種機制可以讓數據在瞬時狀態和持久狀態之間進行轉換。Android系統中主要提供了3種方式用於簡單地實現數據持久化功能,即文件存儲、SharedPreferences存儲以及數據庫存儲。
目錄
文件存儲
將數據存儲到文件中
文件存儲是Android中最基本的一種數據存儲方式,它不對存儲的內容進行任何的格式化處理,所有數據都是原封不動地保存到文件當中的,因而它比較適合用於存儲一些簡單的文本數據或二進制數據。如果你想使用文件存儲的方式來保存一些較爲複雜的文本數據,就需要定義一套自己的格式規範,這樣可以方便之後將數據從文件中重新解析出來
首先創建一個新的項目命名爲FilePersistenceTest項目。並修改activity_main.xml中的代碼,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!--加入了一個EditText,用於輸入文本內容-->
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
運行結果如下。此時,可以輸入任意想輸入的內容,但是按一下back或者退出程序,所輸入的內容都會丟失,因爲它只是瞬時數據。在活動被銷燬後就會被回收。
接下來,修改MainActivity中的代碼,讓數據被回收之前。存儲到文件當中
package com.example.filepersistencetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.widget.EditText;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
private EditText edit;
@Override
protected void onCreate(Bundle savedInstanceState) {//在初始化的時候獲取editText實例
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit=(EditText) findViewById(R.id.edit);//獲取了EditText的實例
}
//定義一個保存數據的函數
//Context 類中提供了一個openFileOutput() 方法,可以用於將數據存儲到指定的文件中
public void save (String inputText){
FileOutputStream out = null;//openFileOutput () 方法返回的是一個FileOutputStream 對象
BufferedWriter writer = null;//用於將文本內容寫入到文件中
try {
out = openFileOutput("data", Context.MODE_PRIVATE);
//用於將數據存儲到指定的文件中
//第一個參數是文件名,在文件創建的時候使用的就是這個名稱,
// 注意這裏指定的文件名不可以包含路徑,因爲所有的文件都是默認存儲到/data/data/<package name>/files/目錄下的
//第二個參數是文件的操作模式,主要有兩種模式可選,MODE_PRIVATE和MODE_APPEND。
//MODE_PRIVATE是默認的操作模式,表示當指定同樣文件名的時候,所寫入的內容將會覆蓋原文件中的內容
//MODE_APPEND則表示如果該文件已存在,就往文件裏面追加內容,不存在就創建新文件。
//openFileOutput () 方法返回的是一個FileOutputStream 對象,
// 得到了這個對象之後就可以使用Java流的方式將數據寫入到文件中了。
writer = new BufferedWriter(new OutputStreamWriter(out));
//FileOutputStream 對象通過OutputStreamWriter建出一個OutputStreamWriter 對象,
// 接着再使用OutputStreamWriter 構建出一個BufferedWriter 對象,
//通過BufferedWriter 對象來將文本內容寫入到文件中
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//這個方法在活動被銷燬之前調用,之後活動的狀態將變爲銷燬狀態。
//保證在活動銷燬之前一定會調用這個方法
//所以通過重載onDestroy() 方法,在其中來保存數據
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();//獲取了EditText中輸入的內容
save(inputText);//調用上面定義的save函數
}
}
運行程序
然後按下Back鍵關閉程序,這時我們輸入的內容就已經保存到文件中了。
接下來,藉助Android Device Monitor工具來查看一下。然而根本找不到。。。網上各種博客說的什麼打開文件夾或者在terminal輸入什麼,全都不行,那些博客基本都是你抄我我抄你的。。。連實現都沒實現過就說了。。。
首先打開SDK路徑是百分百不行的
根本沒有monitor這個東西。既然打不開就不管了。。。直接讀取就好了
從文件中讀取數據
類似於將數據存儲到文件中,Context 類中還提供了一個openFileInput() 方法,用於從文件中讀取數據。這個方法要比openFileOutput() 簡單一些,它只接收一個參數,即要讀取的文件名,然後系統會自動到/data/data/<package name>/files/目錄下去加載這個文件,並返回一個FileInputStream 對象,得到了這個對象之後再通過Java流的方式就可以將數據讀取出來了。
接下來通過修改MainActivity中的代碼,實現得重新啓動程序時EditText中能夠保留我們上次輸入的內容
package com.example.filepersistencetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
private EditText edit;
//定義一個讀入文件的函數
public String load(){
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
//首先通過openFileInput() 方法獲取到了一個FileInputStream 對象
in = openFileInput("data");
//然後藉助它又構建出了一個InputStreamReader 對象
//接着再使用InputStreamReader 構建出一個BufferedReader 對象
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);//進行一行一行的讀取
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
@Override
protected void onCreate(Bundle savedInstanceState) {//在初始化的時候獲取editText實例
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit=(EditText) findViewById(R.id.edit);//獲取了EditText的實例
String inputText = load();//在初始化的時候讀入文件
if (!TextUtils.isEmpty(inputText)) { //如果讀到的內容不爲null
edit.setText(inputText); //調用EditText的setText() 方法將內容填充到EditText裏
edit.setSelection(inputText.length()); //調用setSelection() 方法將輸入光標移動到文本的末尾位置以便於繼續輸入
Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_SHORT).show();
}
}
//定義一個保存數據的函數
//Context 類中提供了一個openFileOutput() 方法,可以用於將數據存儲到指定的文件中
public void save (String inputText){
FileOutputStream out = null;//openFileOutput () 方法返回的是一個FileOutputStream 對象
BufferedWriter writer = null;//用於將文本內容寫入到文件中
try {
out = openFileOutput("data", Context.MODE_PRIVATE);
//用於將數據存儲到指定的文件中
//第一個參數是文件名,在文件創建的時候使用的就是這個名稱,
// 注意這裏指定的文件名不可以包含路徑,因爲所有的文件都是默認存儲到/data/data/<package name>/files/目錄下的
//第二個參數是文件的操作模式,主要有兩種模式可選,MODE_PRIVATE和MODE_APPEND。
//MODE_PRIVATE是默認的操作模式,表示當指定同樣文件名的時候,所寫入的內容將會覆蓋原文件中的內容
//MODE_APPEND則表示如果該文件已存在,就往文件裏面追加內容,不存在就創建新文件。
//openFileOutput () 方法返回的是一個FileOutputStream 對象,
// 得到了這個對象之後就可以使用Java流的方式將數據寫入到文件中了。
writer = new BufferedWriter(new OutputStreamWriter(out));
//FileOutputStream 對象通過OutputStreamWriter建出一個OutputStreamWriter 對象,
// 接着再使用OutputStreamWriter 構建出一個BufferedWriter 對象,
//通過BufferedWriter 對象來將文本內容寫入到文件中
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//這個方法在活動被銷燬之前調用,之後活動的狀態將變爲銷燬狀態。
//保證在活動銷燬之前一定會調用這個方法
//所以通過重載onDestroy() 方法,在其中來保存數據
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();//獲取了EditText中輸入的內容
save(inputText);//調用上面定義的save函數
}
}
注意,上述代碼在對字符串進行非空判斷的時候使用了TextUtils.isEmpty() 方法,這是一個非常好用的方法,它可以一次性進行兩種空值的判斷。當傳入的字符串等於null 或者等於空字符串的時候,這個方法都會返回true ,從而使得我們不需要先單獨判斷這兩種空值再使用邏輯運算符連接起來了。
結果如下圖所示
SharedPreferences存儲
不同於文件的存儲方式,SharedPreferences是使用鍵值對的方式來存儲數據的。也就是說,當保存一條數據的時候,需要給這條數據提供一個對應的鍵,這樣在讀取數據的時候就可以通過這個鍵把相應的值取出來。而且SharedPreferences還支持多種不同的數據類型存儲,如果存儲的數據類型是整型,那麼讀取出來的數據也是整型的;如果存儲的數據是一個字符串,那麼讀取出來的數據仍然是字符串。
將數據存儲到SharedPreferences中
要想使用SharedPreferences來存儲數據,首先需要獲取到SharedPreferences 對象。Android中主要提供了3種方法用於得到SharedPreferences 對象。
Context 類中的getSharedPreferences() 方法
此方法接收兩個參數,第一個參數用於指定SharedPreferences文件的名稱,如果指定的文件不存在則會創建一個,SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目錄下的。第二個參數用於指定操作模式,目前只有MODE_PRIVATE這一種模式可選,它是默認的操作模式,和直接傳入0效果是相同的,表示只有當前的應用程序纔可以對這個SharedPreferences文件進行讀寫。
Activity 類中的getPreferences() 方法
這個方法和Context中的getSharedPreferences() 方法很相似,不過它只接收一個操作模式參數,因爲使用這個方法時會自動將當前活動的類名作爲SharedPreferences的文件名。
PreferenceManager 類中的getDefaultSharedPreferences() 方法
這是一個靜態方法,它接收一個Context 參數,並自動使用當前應用程序的包名作爲前綴來命名SharedPreferences文件。得到了SharedPreferences 對象之後,就可以開始向SharedPreferences文件中存儲數據了,主要可以分爲3步實現。
- 調用SharedPreferences 對象的edit() 方法來獲取一個SharedPreferences.Editor 對象。
- 向SharedPreferences.Editor 對象中添加數據,比如添加一個布爾型數據就使用putBoolean() 方法,添加一個字符串則使用putString() 方法,以此類推。
- 調用apply() 方法將添加的數據提交,從而完成數據存儲操作。
接下來我們將activity_main.xml中的代碼改爲:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/save_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save data"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
這裏只是簡單的防止一個按鈕,用於將一些數據存到SharedPreferences文件當中。修改MainActivity中的代碼,如下所示:
package com.example.filepersistencetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button saveData = (Button) findViewById(R.id.save_data);
//註冊一個按鈕點擊事件,
saveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通過getSharedPreferences() 方法指定SharedPreferences的文件名爲data
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
//向這個對象添加3重不同類型的數據
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
//最後通過apply()方法提交,從而完成數據存儲的操作
editor.apply();
}
});
}
}
從SharedPreferences中讀取數據
SharedPreferences 對象中提供了一系列的get 方法,用於對存儲的數據進行讀取,每種get 方法都對應了SharedPreferences.Editor中的一種put 方法,比如讀取一個布爾型數據就使用getBoolean() 方法,讀取一個字符串就使用getString() 方法。這些get 方法都接收兩個參數,第一個參數是鍵,傳入存儲數據時使用的鍵就可以得到相應的值了;第二個參數是默認值,即表示當傳入的鍵找不到對應的值時會以什麼樣的默認值進行返回。
修改activity_main.xml中的代碼,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/save_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save data"
/>
<Button
android:id="@+id/restore_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Restore data"
/>
</LinearLayout>
這裏增加了一個還原數據的按鈕,我們希望通過點擊這個按鈕來從SharedPreferences文件中讀取數據。修改MainActivity中的代碼,如下所示:
package com.example.filepersistencetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button saveData = (Button) findViewById(R.id.save_data);
//註冊一個按鈕點擊事件,保存數據
saveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通過getSharedPreferences() 方法指定SharedPreferences的文件名爲data
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
//向這個對象添加3重不同類型的數據
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
//最後通過apply()方法提交,從而完成數據存儲的操作
editor.apply();
}
});
Button restoreData = (Button) findViewById(R.id.restore_data);
//設置一個按鈕點擊事件,恢復數據
restoreData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//首先通過getSharedPreferences() 方法得到了SharedPreferences 對象
SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
//分別調用它的getString() 、getInt() 和getBoolean() 方法,
//去獲取前面所存儲的姓名、年齡和是否已婚,
// 如果沒有找到相應的值,就會使用方法中傳入的默認值來代替,
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean married = pref.getBoolean("married", false);
//通過Log將這些值打印出來。
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "age is " + age);
Log.d("MainActivity", "married is " + married);
}
});
}
}
運行結果如下圖所示
實現記住密碼功能
之前博文《Android學習筆記之——通過broadcast實現強制下線功能》實現了登陸一個賬號,然後進去再註銷所有活動的功能。再很多的軟件中,都存在記錄密碼這一功能。
首先修改activity_login.xml中的代碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="Account:" />
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="Password:" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:inputType="textPassword" />
</LinearLayout>
<!--複選框控件-->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/remember_pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="Remember password" />
</LinearLayout>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="Login" />
</LinearLayout>
這裏使用到了一個新控件CheckBox。這是一個複選框控件,用戶可以通過點擊的方式來進行選中和取消,我們就使用這個控件來表示用戶是否需要記住密碼。
然後修改LoginActivity中的代碼,如下所示:
package com.example.broadcastbestpractice;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
//繼承baseactivity,其內會控制各種activity的啓動與銷燬
public class LoginActivity extends BaseActivity {
//定義一些SharedPreferences的對象
private SharedPreferences pref;//存數據的SharedPreferences 對象
private SharedPreferences.Editor editor;//讀數據
private CheckBox rememberPass;
private EditText accountEdit;
private EditText passwordEdit;
private Button login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); //加載佈局login.xml的佈局
//獲取一個SharedPreferences 對象
pref = PreferenceManager.getDefaultSharedPreferences(this);
rememberPass = (CheckBox) findViewById(R.id.remember_pass);
//調用findViewById() 方法分別獲取到賬號輸入框、密碼輸入框以及登錄按鈕的實例
accountEdit=(EditText) findViewById(R.id.account);//編輯文本(輸入賬號)實例化
passwordEdit= (EditText) findViewById(R.id.password);//編輯文本(輸入密碼)實例化
//調用pref的getBoolean() 方法去獲取remember_password 這個鍵對應的值。
//一開始不存在的時候,默認爲false
boolean isRemember = pref.getBoolean("remember_password", false);
if (isRemember) {//如果這個鍵值爲true,也就是有鍵值。那麼將賬號和密碼都讀入一下。
// 將賬號和密碼都設置到文本框中
String account = pref.getString("account", "");
String password = pref.getString("password", "");
//通過setText將text設入。
accountEdit.setText(account);
passwordEdit.setText(password);
rememberPass.setChecked(true);
}
login=(Button) findViewById(R.id.login);//登陸按鍵實例化
//在登錄按鈕的點擊事件裏面對輸入的賬號和密碼進行判斷
login.setOnClickListener(new View.OnClickListener() {//爲登陸按鍵註冊監聽器
@Override
public void onClick(View v) {
String account= accountEdit.getText().toString();
String password= passwordEdit.getText().toString();
//判斷
//如果賬號是admin且密碼是123456,就認爲登錄成功
if (account.equals("admin") && password.equals("123456")) {
//////////////////////////////////////////////////////
editor = pref.edit();//跟前面一樣,需要調用edit()方法纔可以編輯
if (rememberPass.isChecked()) { // 登錄成功後會檢查複選框是否被選中
//如果勾選了,就將賬號和密碼的值加進去
//向editor對象中加載數據
editor.putBoolean("remember_password", true);//將remember_password 設置爲true
//然後把account 和password 對應的值都存入到SharedPreferences文件當中並提交
editor.putString("account", account);
editor.putString("password", password);
} else {//如果沒有勾選則清空一下
editor.clear();//將SharedPreferences文件中的數據全部清除掉
}
//最後通過apply()方法提交,從而完成數據存儲的操作
editor.apply();
//////////////////////////////////////////////////////
Intent intent = new Intent(LoginActivity.this, MainActivity.class);//如果成功就通過intent轉跳到mainactivity
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "account or password is invalid", Toast.LENGTH_SHORT).show();
}
}
});
}
}
SQLite數據庫存儲
SQLite是一款輕量級的關係型數據庫,它的運算速度非常快,佔用資源很少,通常只需要幾百KB的內存就足夠了,因而特別適合在移動設備上使用。
Android爲了讓我們能夠更加方便地管理數據庫,專門提供了一個SQLiteOpenHelper幫助類。
SQLiteOpenHelper是一個抽象類,這意味着如果我們想要使用它的話,就需要創建一個自己的幫助類去繼承它。SQLiteOpenHelper中有兩個抽象方法,分別是onCreate() 和onUpgrade() ,我們必須在自己的幫助類裏面重寫這兩個方法,然後分別在這兩個方法中去實現創建、升級數據庫的邏輯。
SQLiteOpenHelper中還有兩個非常重要的實例方法:getReadableDatabase() 和getWritableDatabase() 。這兩個方法都可以創建或打開一個現有的數據庫(如果數據庫已存在則直接打開,否則創建一個新的數據庫),並返回一個可對數據庫進行讀寫操作的對
象。不同的是,當數據庫不可寫入的時候(如磁盤空間已滿),getReadableDatabase()方法返回的對象將以只讀的方式去打開數據庫,而getWritableDatabase() 方法則將出現異常。
SQLiteOpenHelper中有造方法中:
- 第一個參數是Context,,必須要有它才能對數據庫進行操作。
- 第二個參數是數據庫名,創建數據庫時使用的就是這裏指定的名稱。
- 第三個參數允許我們在查詢數據的時候返回一個自定義的Cursor,一般都是傳入null。
- 第四個參數表示當前數據庫的版本號,可用於對數據庫進行升級操作。
構建出SQLiteOpenHelper的實例之後,再調用它的getReadableDatabase() 或getWritableDatabase() 方法就能夠創建數據庫了,數據庫文件會存放在/data/data/<package name>/databases/目錄下。此時,重寫的onCreate() 方法也會得到執行,所以通常會在這裏去處理一些創建表的邏輯。
使用LitePal操作數據庫