- Android系統(tǒng)提供了三種方式用于簡(jiǎn)單地實(shí)現(xiàn)數(shù)據(jù)持久化功能
- 文件存儲(chǔ)
- SharedPreferences存儲(chǔ)
- 數(shù)據(jù)庫(kù)存儲(chǔ)
文件存儲(chǔ)
- 所有的數(shù)據(jù)都會(huì)原封不動(dòng)的保存到文件當(dāng)中,比較適合存儲(chǔ)簡(jiǎn)單的文本數(shù)據(jù)或二進(jìn)制數(shù)據(jù)
存儲(chǔ)數(shù)據(jù)
-
Context類(lèi)中有一個(gè)openFileOutput()方法编整,用來(lái)存儲(chǔ)數(shù)據(jù)舅踪,這個(gè)方法接受兩個(gè)參數(shù)
-
第一個(gè)參數(shù)是文件名,在文件創(chuàng)建的時(shí)候使用的名字
- 文件名不包括路徑
- 所有的文件默認(rèn)都存儲(chǔ)在/data/data/<package name>/files/這個(gè)目錄下
-
第二個(gè)參數(shù)是文件的操作模式
- MODE_PRIVATE
- 默認(rèn)操作模式
- 當(dāng)指定同樣的文件名時(shí),新寫(xiě)入的內(nèi)容會(huì)覆蓋原來(lái)的內(nèi)容
- MODE_APPEND
- 如果文件存在了,就追加寫(xiě)入內(nèi)容
- 文件不存在就創(chuàng)建新的文件
- MODE_PRIVATE
這個(gè)方法返回的是一個(gè)FileOutputStream對(duì)象,可以通過(guò)Java流的方式將數(shù)據(jù)寫(xiě)入到文件中
-
例子
public void save(String inputText){ FileOutputStream out = null; BufferedWriter writer = null; try{ out = openFileOutput("data",Context.MODE_PRIVATE); write = new BufferedWriter(new OutputStreamWrite(out)); write.write(inputText); } catch(IOException e){ e.printStackTrace(); } finally{ try{ if (writer != null){ writer.close() } } catch(IOException e){ e.printStackTrace(); } } }
-
讀取數(shù)據(jù)
使用openFileInput()方法讀取數(shù)據(jù)拌蜘,這個(gè)方法只接收一個(gè)參數(shù),就是要讀取的文件名
系統(tǒng)會(huì)自動(dòng)去默認(rèn)的目錄下加載要讀取的文件牙丽,然后返回一個(gè)FIleInputStream對(duì)象简卧,然后再通過(guò)Java流的方式操作
-
例子
public String load(){ FileInputStream對(duì)象 in = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try{ // 獲取一個(gè)FileInputStream對(duì)象 in = openFileInput("data"); 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(); }
SharedPreferences存儲(chǔ)
向SharedPreferences存儲(chǔ)數(shù)據(jù)
-
Context類(lèi)中的getSharedPreferences()方法
- 這個(gè)方法接收兩個(gè)參數(shù)
- 參數(shù)1:用來(lái)指定SharedPreferences文件的名稱,如果指定的文件不存在就創(chuàng)建一個(gè)(文件都存放在/data/data/<pacakagename>/shared_prefs/目錄下)
- 參數(shù)2:用于指定操作模式烤芦,只有一種模式MODE_PRIVATE举娩,也可以直接傳入0
- 在Android4.2中被廢棄的模式:MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE
- 在Android6.0中被廢棄的模式:MODE_MULTI_PROCESS
-
Activity類(lèi)中的getSharedPreferences()方法
- 和上面的方法相似,但是只接收一個(gè)參數(shù)
- 參數(shù):操作模式
- 使用這個(gè)方法的時(shí)候會(huì)自動(dòng)將當(dāng)前活動(dòng)的類(lèi)名作為SharedPreferences的文件名
-
PreferenceManager類(lèi)中的getDefaultSharedPreferences()方法
- 靜態(tài)方法,接收一個(gè)Context參數(shù)晓铆,自動(dòng)使用當(dāng)前應(yīng)用程序的包名作為前綴名來(lái)命名SharedPreferences文件
- 存儲(chǔ)數(shù)據(jù)分為三步
- 調(diào)用SharedPreferences對(duì)象的edit()方法來(lái)獲取一個(gè)SharedPreferences.Editor對(duì)象
- 向SharedPreferences.Editor對(duì)象中添加數(shù)據(jù)
- 調(diào)用apply()方法將添加的數(shù)據(jù)提交即可
-
例子
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 view) { SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit(); editor.putString("name","Tom"); editor.putInt("age",28); editor.putBoolean("married",false); editor.apply(); } }); } }
- 通過(guò)getSharedPreferences()方法指定SharedPreferences的文件名叫data
從SharedPreferences讀取數(shù)據(jù)
SharedPreferences對(duì)象中提供了一系列的get方法來(lái)讀取數(shù)據(jù)勺良,get方法對(duì)應(yīng)put方法(putString對(duì)應(yīng)getString)
-
這些get方法接收兩個(gè)參數(shù)
- 參數(shù)1:鍵,傳入存儲(chǔ)數(shù)據(jù)時(shí)使用的鍵
- 參數(shù)2:默認(rèn)值骄噪,當(dāng)傳入的鍵找不到對(duì)應(yīng)的值的時(shí)候以默認(rèn)的值進(jìn)行返回
-
例子
public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button readData = (Button) findViewById(R.id.read_data); readData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE); String name = pref.getString("name",""); int age = pref.getInt("age",0); boolean married = pref.getBoolean("married",false); Log.d("MainActivity","name is "+name); } }); } }
SQLite數(shù)據(jù)庫(kù)
創(chuàng)建數(shù)據(jù)庫(kù)
借助SQLiteOpenHelper類(lèi)來(lái)操作數(shù)據(jù)庫(kù)
SQLiteOpenHelper類(lèi)是一個(gè)抽象類(lèi)尚困,必須自己寫(xiě)一個(gè)類(lèi)來(lái)繼承它,自己寫(xiě)的類(lèi)必須重寫(xiě)其中的onCreate()方法和onUpgrade()方法
-
SQLiteOpenHelper類(lèi)中的兩個(gè)重要的方法getReadableDatabase()和getWritableDtatabase()
- 這兩個(gè)方法都可以創(chuàng)建或打開(kāi)一個(gè)數(shù)據(jù)庫(kù)(數(shù)據(jù)庫(kù)存在就打開(kāi)链蕊,不存在就創(chuàng)建)事甜,返回返回一個(gè)可以對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫(xiě)操作的對(duì)象
- 當(dāng)數(shù)據(jù)庫(kù)不能寫(xiě)入的時(shí)候,getReadableDatabase()方法返回的對(duì)象只能以只讀的方式打開(kāi)數(shù)據(jù)庫(kù)滔韵,getWritableDtatabase()方法會(huì)出現(xiàn)異常
-
SQLiteOpenHelper類(lèi)有兩個(gè)構(gòu)造方法逻谦,構(gòu)造方法有四個(gè)參數(shù)
- 參數(shù)1:Context,必須有它才能操作數(shù)據(jù)庫(kù)
- 參數(shù)2:數(shù)據(jù)庫(kù)名字陪蜻,創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候使用這個(gè)名字
- 參數(shù)3:查詢數(shù)據(jù)的時(shí)候返回一個(gè)自定義的Cursor邦马,可以傳入null
- 參數(shù)4:數(shù)據(jù)庫(kù)的版本號(hào)
數(shù)據(jù)庫(kù)文件存放在/data/data/<package_name>/databases/這個(gè)目錄下
-
例子
-
創(chuàng)建一個(gè)MyDatabaseHelper類(lèi)繼承SQLiteOpenHelper類(lèi)
public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK = "create table Book(" + "id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text)"; 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) { db.execSQL(CREATE_BOOK); Toast.makeText(mContext, "創(chuàng)建成功", Toast.LENGTH_SHORT).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
- 定義一個(gè)類(lèi),然后在類(lèi)中寫(xiě)一個(gè)創(chuàng)建數(shù)據(jù)庫(kù)的語(yǔ)句
- 重寫(xiě)onCreate()方法宴卖,在這個(gè)方法中調(diào)用剛才寫(xiě)的語(yǔ)句
-
然后創(chuàng)建數(shù)據(jù)庫(kù)
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button createDatabase = (Button) findViewById(R.id.create_database); createDatabase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dbHelper.getWritableDatabase(); } }); } }
-
升級(jí)數(shù)據(jù)庫(kù)
使用onUpgrade()方法來(lái)升級(jí)數(shù)據(jù)庫(kù)
-
例子
public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK = "create table Book(" + "id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text)"; private Context mContext; public static final String CREATE_CATEGORY = "create table Category(" + "id integer primary key autoincrement," +"category name text," +"category code integer)"; public MyDatabaseHelper(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, "創(chuàng)建成功", Toast.LENGTH_SHORT).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 當(dāng)表Book和Category存在的時(shí)候就刪除 db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists Category"); onCreate(db); } }
-
要執(zhí)行onUpgrade()方法滋将,只需要在SQLiteOpenHelper的構(gòu)造方法中,修改第四個(gè)參數(shù)就可以
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 因?yàn)橹暗谒膫€(gè)參數(shù)的值是1症昏,這里只要比1大就行 dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2); Button createDatabase = (Button) findViewById(R.id.create_database); createDatabase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dbHelper.getWritableDatabase(); } }); } }
添加數(shù)據(jù)
SQLiteDatabae中提供了一個(gè)insert()方法來(lái)添加數(shù)據(jù)
-
insert(table_name,null,ContentValues)
- 參數(shù)1:表名
- 參數(shù)2:在未指定添加數(shù)據(jù)的情況下給某些可以為空的列自動(dòng)賦值NULL随闽,可以直接寫(xiě)null
- 參數(shù)3:ContentValues對(duì)象,這個(gè)對(duì)象提供了一系列的put()方法肝谭,將表中每個(gè)列名以及相應(yīng)的待添加數(shù)據(jù)傳入就行了
-
例子
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button addData = (Button) findViewById(R.id.add_data); addData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); // 下面的代碼用來(lái)組裝一條要插入數(shù)據(jù)庫(kù)中的數(shù)據(jù) values.put("name","A Book"); // put()第一個(gè)參數(shù)是表中的列名,第二個(gè)是要插入的值 values.put("author","Jone Doe"); values.put("pages",444); values.put("price",55.45); // 將組裝好的數(shù)據(jù)插入到數(shù)據(jù)庫(kù)中 db.insert("Book",null,values); values.clear(); } }); } }
更新數(shù)據(jù)
SQLiteDatabae中提供了一個(gè)update()方法來(lái)添加數(shù)據(jù)
-
update(table_name,ContentValues,args,args)
- 參數(shù)1:表名
- 參數(shù)2:ContentValues對(duì)象攘烛,更新的數(shù)據(jù)在這里完成組裝
- 參數(shù)3和4用于約束更新的范圍魏滚,是哪一行還是哪幾行,不指定就默認(rèn)更新所有行
-
例子
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button updateData = (Button) findViewById(R.id.update_data); updateData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("price",56.78); // 參數(shù)3相當(dāng)于SQL語(yǔ)句中的where部分 // 這里表示更新所有name等于?的行医寿,?在這里表示占位符栏赴,具體的值通過(guò)參數(shù)4提供 // 參數(shù)4提供了一個(gè)字符串?dāng)?shù)據(jù)蘑斧,來(lái)給參數(shù)3中的占位符指定相應(yīng)的內(nèi)容 db.update("Book",values,"name=?",new String[]{"A Book"}); } }); } }
刪除數(shù)據(jù)
SQLiteDatabae中提供了一個(gè)delete()方法來(lái)添加數(shù)據(jù)
-
delete(table_name,args,args)
- 參數(shù)1:表名
- 參數(shù)2和參數(shù)3:用于約束刪除哪一行或者哪幾行的數(shù)據(jù)靖秩,不指定就默認(rèn)刪除所有行
-
例子
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button deleteButton = (Button) findViewById(R.id.delete_data); deleteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); // 這里表示刪除頁(yè)數(shù)超過(guò)300的數(shù)據(jù) db.delete("Book","pages > ?",new String[]{"300"}); } }); } }
查詢數(shù)據(jù)
SQLiteDatabae中提供了一個(gè)query()方法來(lái)添加數(shù)據(jù)
調(diào)用query()方法之后會(huì)返回一個(gè)Cursor對(duì)象,查詢到的數(shù)據(jù)都從這個(gè)對(duì)象中取出
-
query()方法有7個(gè)參數(shù)
- 參數(shù)1:表名
- 參數(shù)2:指定去查詢哪幾列竖瘾,不指定就默認(rèn)查詢所有列
- 參數(shù)3沟突,參數(shù)4:用于約束查詢某一行或某幾行的數(shù)據(jù),不指定就默認(rèn)查詢所有行的數(shù)據(jù)
- 參數(shù)5:用于指定需要去group by的列捕传,不指定就表示不對(duì)查詢結(jié)果進(jìn)行g(shù)roup by的操作
- 參數(shù)6:用于對(duì)group by之后的數(shù)據(jù)進(jìn)行進(jìn)一步過(guò)濾惠拭,不指定就不進(jìn)行過(guò)濾
- 參數(shù)7:指定查詢結(jié)果的排序方式,不指定就表示使用默認(rèn)的排序方式
-
例子
public class MainActivity extends AppCompatActivity{ private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button queryButton = (Button) findViewById(R.id.retrieve_data); queryButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SQLiteDatabase db = dbHelper.getWritableDatabase(); // 查詢表中所有的數(shù)據(jù) 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")); }while (cursor.moveToNext()); } cursor.close(); } }); } }