005 Android之数据存储
文章目錄
- Android文件系統(tǒng)
- Android文件的訪問(wèn)權(quán)限
- 文件訪問(wèn)權(quán)限實(shí)例
- 數(shù)據(jù)存儲(chǔ)方式
- 內(nèi)部存儲(chǔ)
- 內(nèi)部存儲(chǔ)實(shí)例
- 外部存儲(chǔ)
- Shared Preferences
- Shared Preferences實(shí)例
- sqlite數(shù)據(jù)庫(kù)
- sqlite概述
- Android中訪問(wèn)Sqlite數(shù)據(jù)庫(kù)的類(lèi)
- SQLiteOpenHelper類(lèi)的使用
- SQLiteDatabase的使用
Android文件系統(tǒng)
在Android中,每一個(gè)應(yīng)用都是一個(gè)獨(dú)立的用戶(hù)。文件或者文件夾的權(quán)限使用10個(gè)字母來(lái)表示
第一個(gè)字母:
- d表示文件夾
- -表示文件
第一組rwx,表示的是文件擁有者(owner)對(duì)文件的權(quán)限
- r:read
- w:write
- x:execute
第二組rwx,表示的是文件擁有者屬于同一用戶(hù)組的用戶(hù)對(duì)文件的權(quán)限
第三組rwx,表示的是其他用戶(hù)對(duì)文件的權(quán)限
rwx分別代表數(shù)值421
Android文件的訪問(wèn)權(quán)限
Android中的文件是有很多權(quán)限的,我們自己創(chuàng)建的文件也是會(huì)有權(quán)限的,權(quán)限相關(guān)API
FileInputStream openFileOutput(String name); //讀取文件 FileOutputStream openFileOutput(String name,int mode); //模式這個(gè)API訪問(wèn)的目錄是data/data包名/files,打開(kāi)應(yīng)用程序的數(shù)據(jù)文件夾下的name文件對(duì)應(yīng)輸出流有下面幾種
| Context.MODE_PRIVATE | 私有模式,第二次讀寫(xiě)會(huì)覆蓋文件 |
| Context.MODE_APPEND | 追加方式,判斷文件存在,追加到文件末尾 |
| Context.MODE_WORLD_READABLE | 其他程序可以讀(不推薦使用) |
| Context.MODE_WORLD_WRITEABLE | 其他程序可以寫(xiě)(不推薦使用 |
文件訪問(wèn)權(quán)限實(shí)例
界面代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_private"android:onClick="onClick"android:text="私有方式"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_append"android:onClick="onClick"android:text="追加"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_read"android:onClick="onClick"android:text="全局可讀"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_write"android:onClick="onClick"android:text="全局可寫(xiě)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_rw"android:onClick="onClick"android:text="全局可讀可寫(xiě)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_private"android:onClick="onClick"android:text="私有方式"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>設(shè)置五個(gè)按鈕,分別對(duì)應(yīng)不同的文件權(quán)限,然后編寫(xiě)響應(yīng)事件
public void onClick(View view) {int id=view.getId();String name=null;int mode=0;switch (id){case R.id.btn_private:name="private.txt";mode=Context.MODE_PRIVATE;break;case R.id.btn_append:name="append.txt";mode=Context.MODE_APPEND;break;case R.id.btn_global_read:name="global_read.txt";mode=Context.MODE_WORLD_READABLE;break;case R.id.btn_global_write:name="global_write.txt";mode=Context.MODE_WORLD_WRITEABLE;break;case R.id.btn_global_rw:name="global_rw.txt";mode=Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE;break;}try {FileOutputStream outputStream=openFileOutput(name,mode);String content="這里是內(nèi)容";outputStream.write(content.getBytes());outputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}當(dāng)點(diǎn)擊按鈕以后
在files目錄下會(huì)生成不同的文件
數(shù)據(jù)存儲(chǔ)方式
在Android SDK中關(guān)于數(shù)據(jù)存儲(chǔ)一共有以下幾種:
內(nèi)部存儲(chǔ)
內(nèi)部存儲(chǔ)只能存儲(chǔ)在自身app的數(shù)據(jù)區(qū)
目錄:data/data/包名/xxx.txt
寫(xiě)入和讀取需要以下幾個(gè)類(lèi):
- 文件信息類(lèi):File類(lèi)
- 保存文件使用:FileOutputStream類(lèi)
- 讀取文件使用:FileInputStream類(lèi)
- 字節(jié)流轉(zhuǎn)換成字符流:BufferedReader類(lèi)
內(nèi)部存儲(chǔ)實(shí)例
實(shí)例:用戶(hù)登陸程序
功能:登陸之后勾選記住用戶(hù)名,下次登陸可以直接填充
分析思路:
布局代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><EditTextandroid:id="@+id/edit_user"android:hint="請(qǐng)?jiān)诖溯斎胗脩?hù)名"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/edit_pass"android:hint="請(qǐng)?jiān)诖溯斎朊艽a"android:layout_width="match_parent"android:layout_height="wrap_content" /><CheckBoxandroid:id="@+id/checkbox"android:text="記住用戶(hù)名"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btnclick"android:onClick="btnClick"android:text="登陸"android:layout_width="wrap_content"android:layout_height="wrap_content" /> </LinearLayout>接著編寫(xiě)按鈕響應(yīng)事件,用于保存用戶(hù)名和密碼
public void btnClick(View view) {//獲取用戶(hù)名EditText editText=findViewById(R.id.edit_user);String user=editText.getText().toString();//獲取密碼EditText editText2=findViewById(R.id.edit_pass);String pass=editText.getText().toString();//模擬判斷登陸情況if (!user.equals(pass)){return;}Toast.makeText(this,"成功登陸",Toast.LENGTH_LONG).show();//獲取界面對(duì)象CheckBox checkBox=findViewById(R.id.checkbox);//判斷是否被選中if (checkBox.isChecked()){//保存用戶(hù)名String path="/data/data/com.example.a87321.login/config.txt";File file=new File(path);try {FileOutputStream outputStream=new FileOutputStream(file);byte bytes[]=user.getBytes();outputStream.write(bytes);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}運(yùn)行程序
在/data/data/包名/這個(gè)路徑下,可以看到保存的config文件;接著編寫(xiě)代碼,在主函數(shù)入口讀取配置文件的帳號(hào)密碼
private void InitData() {//獲取控件對(duì)象EditText editText=findViewById(R.id.edit_user);//讀取配置文件的用戶(hù)名,設(shè)置對(duì)象String packageName=getPackageName();String path="/data/data/"+packageName+"/config.txt";File file=new File(path);try {FileInputStream inputStream=new FileInputStream(file);byte bytes[]=new byte[(int)file.length()];inputStream.read(bytes);String s=new String(bytes);editText.setText(s);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}接著在界面加載時(shí),就會(huì)自動(dòng)讀取用戶(hù)名,顯示到界面,效果如圖:
外部存儲(chǔ)
外部存儲(chǔ)就是存儲(chǔ)在SD卡中
SD卡的路徑
- sdcard:2.3之前的SD卡路徑
- mnt/sdcard:4.3之前的SD卡路徑
- storage/sdcard:4.3之后的SD卡路徑
使用方式和內(nèi)部存儲(chǔ)差不多,只是寫(xiě)入的路徑不同,這里不再舉例
Shared Preferences
Shared Preferences是使用的最多的數(shù)據(jù)存儲(chǔ)方式,這種數(shù)據(jù)存儲(chǔ)方式保存的信息只能是基本數(shù)據(jù)類(lèi)型和字符串,適用于保存解鎖密碼用戶(hù)名以及一些配置信息。
核心原理:讀取寫(xiě)入操作的是app安裝目錄下的/data/data/<package name>/shared_prefs目錄下,保存的文件是xml格式
使用Shared Preferences寫(xiě)入數(shù)據(jù)
Shared Preferences是一個(gè)接口,只提供讀取數(shù)據(jù)的功能;Shared Preferences的內(nèi)部接口Editor類(lèi)的edit()方法,提供寫(xiě)入功能。使用步驟如下:
Shared Preferences實(shí)例
界面代碼如下:
<?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"><EditTextandroid:id="@+id/edit1"android:hint="請(qǐng)?jiān)诖溯斎朊艽a"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_set"android:text="保存口令"android:textSize="20sp"android:onClick="btnClick"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_get"android:text="獲取口令"android:textSize="20sp"android:onClick="btnClick"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>接著編寫(xiě)響應(yīng)事件保存pass
private void setPass() {//獲取口令EditText editText=findViewById(R.id.edit1);String pass=editText.getText().toString();//獲取SharedPreferences對(duì)象SharedPreferences sp=getSharedPreferences("lock",Context.MODE_PRIVATE);//獲取Editor對(duì)象SharedPreferences.Editor editor=sp.edit();//壓入數(shù)據(jù)editor.putString("pass",pass);//提交保存editor.commit();//提示信息Toast.makeText(this,"保存完成",Toast.LENGTH_LONG).show();實(shí)際效果如圖:
點(diǎn)擊保存口令以后
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-0cvKULbO-1623032601181)(005 Android之?dāng)?shù)據(jù)存儲(chǔ).assets/1622904828683.png)]
會(huì)生成shared_prefs文件夾,并產(chǎn)生一個(gè)xml文件,里面存儲(chǔ)的是保存的pass數(shù)據(jù)。接著來(lái)完成pass的讀取操作
private void getPass() {//獲取SharedPreferences對(duì)象SharedPreferences sp=getSharedPreferences("lock",Context.MODE_PRIVATE);//獲取數(shù)據(jù)String pass=sp.getString("pass","none");if (pass.equals("none")==false){//提示信息Toast.makeText(this,"口令:"+pass,Toast.LENGTH_LONG).show();}}讀取操作相對(duì)要比寫(xiě)入簡(jiǎn)單的多,直接調(diào)用getString方法就能獲取數(shù)據(jù),效果如圖:
sqlite數(shù)據(jù)庫(kù)
sqlite概述
Sqlite是一款非常優(yōu)秀且廣泛使用于嵌入式軟件中的數(shù)據(jù)庫(kù),它的主要特點(diǎn),一是小巧,二是免費(fèi)開(kāi)源。基于這兩點(diǎn),Google的android系統(tǒng)內(nèi)置了Sqlite,適用于一些有規(guī)則的數(shù)據(jù),比如電話信息;與所有數(shù)據(jù)庫(kù)一樣,具有增刪改查的功能
Android中訪問(wèn)Sqlite數(shù)據(jù)庫(kù)的類(lèi)
Android中有兩個(gè)類(lèi)用于訪問(wèn)sqlite數(shù)據(jù)庫(kù)
SQLiteOpenHelper是SQLiteDatabase的一個(gè)幫助類(lèi),用來(lái)管理數(shù)據(jù)庫(kù)的創(chuàng)建和版本的更新。一般是建立一個(gè)類(lèi)繼承它,并實(shí)現(xiàn)onCreate和onUpgrade方法
| SQLiteOpenHelper | 構(gòu)造方法 |
| onCreate | 第一次創(chuàng)建數(shù)據(jù)庫(kù)時(shí)調(diào)用 |
| onUpgrade | 版本更新時(shí)調(diào)用 |
| getWritableDatabase | 創(chuàng)建數(shù)據(jù)庫(kù),并以讀寫(xiě)方式打開(kāi)數(shù)據(jù)庫(kù),磁盤(pán)滿(mǎn)了不能寫(xiě)時(shí)會(huì)出錯(cuò) |
| getReadableDatabase | 創(chuàng)建數(shù)據(jù)庫(kù),先以讀寫(xiě)方式打開(kāi)數(shù)據(jù)庫(kù),磁盤(pán)滿(mǎn)了再以只讀方式打開(kāi) |
SQLiteDatabase是一個(gè)數(shù)據(jù)庫(kù)訪問(wèn)類(lèi),這個(gè)類(lèi)封裝了一系列數(shù)據(jù)庫(kù)操作的API,可以對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查
| delete | 刪除數(shù)據(jù)行 |
| insert | 添加數(shù)據(jù)行 |
| update | 更新數(shù)據(jù)行 |
| execSQL | 執(zhí)行一個(gè)sql語(yǔ)句 |
| close | 關(guān)閉數(shù)據(jù)庫(kù) |
| query | 查詢(xún)指定的數(shù)據(jù)表返回一個(gè)帶游標(biāo)的數(shù)據(jù)集 |
| rawQuery | 運(yùn)行一個(gè)預(yù)置的SQL語(yǔ)句,返回一個(gè)帶游標(biāo)的數(shù)據(jù)集 |
SQLiteOpenHelper類(lèi)的使用
首先編寫(xiě)界面代碼,設(shè)置6個(gè)按鈕,分別對(duì)應(yīng)不同的數(shù)據(jù)庫(kù)功能
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn1"android:onClick="btnCreate"android:text="創(chuàng)建數(shù)據(jù)庫(kù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn2"android:onClick="btnUpdate"android:text="更新數(shù)據(jù)庫(kù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn3"android:onClick="btnInsert"android:text="插入數(shù)據(jù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn4"android:onClick="btnUpdateData"android:text="更新數(shù)據(jù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn5"android:onClick="btnSelectData"android:text="查詢(xún)數(shù)據(jù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn6"android:onClick="btnDelData"android:text="刪除數(shù)據(jù)"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-nIVwT87i-1623032601186)(005 Android之?dāng)?shù)據(jù)存儲(chǔ).assets/1622955011480.png)]
接著新建一個(gè)類(lèi),并繼承SQLiteOpenHelper
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-bS4rce2R-1623032601191)(005 Android之?dāng)?shù)據(jù)存儲(chǔ).assets/1622955077781.png)]
然后重寫(xiě)onCreate和onUpgrade方法
然后實(shí)現(xiàn)構(gòu)造方法
重寫(xiě)onCreate方法,創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
@Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {//輸出日志Log.i("DBHelper","Create a database");//創(chuàng)建數(shù)據(jù)庫(kù)的sql語(yǔ)句String sql="create table user(id int,name varchar(20))";//執(zhí)行創(chuàng)建數(shù)據(jù)庫(kù)操作sqLiteDatabase.execSQL(sql);}重寫(xiě)upgrade方法
@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {//輸出日志Log.i("DBHelper","update a database");}接著編寫(xiě)創(chuàng)建數(shù)據(jù)庫(kù)按鈕的響應(yīng)事件
public void btnCreate(View view) {//創(chuàng)建一個(gè)DatabaseHelper對(duì)象DBHelper dbHelper=new DBHelper(MainActivity.this,"test.db",null,1);//取得一個(gè)只讀的數(shù)據(jù)庫(kù)對(duì)象SQLiteDatabase db1=dbHelper.getReadableDatabase();db1.close();}點(diǎn)擊創(chuàng)建數(shù)據(jù)庫(kù)
即可在database目錄下生成數(shù)據(jù)庫(kù)文件
編寫(xiě)更新數(shù)據(jù)庫(kù)響應(yīng)事件
public void btnUpdate(View view) {DBHelper dbHelper2=new DBHelper(MainActivity.this,"test.db",null,2);//更新版本SQLiteDatabase db2=dbHelper2.getReadableDatabase();db2.close();}在點(diǎn)擊更新數(shù)據(jù)之后,會(huì)自動(dòng)調(diào)用onUpgrade方法打印日志
SQLiteDatabase的使用
插入數(shù)據(jù)
public void btnInsert(View view) {//獲取存放數(shù)據(jù)的ContentValues對(duì)象ContentValues values=new ContentValues();//向ContentValues中存放數(shù)據(jù)values.put("id",1);values.put("name","zhangsan");//獲取數(shù)據(jù)庫(kù)對(duì)象DBHelper dbhelper3=new DBHelper(this,"test.db",null,2);SQLiteDatabase db3=dbhelper3.getWritableDatabase();//數(shù)據(jù)庫(kù)執(zhí)行插入命令db3.insert("user",null,values);db3.close();}更新數(shù)據(jù)
public void btnUpdateData(View view) {//準(zhǔn)備要更新的數(shù)據(jù)對(duì)象ContentValues values2=new ContentValues();values2.put("name","lisi");//獲取數(shù)據(jù)庫(kù)對(duì)象DBHelper dbhelper4=new DBHelper(this,"test.db",null,2);SQLiteDatabase db4=dbhelper4.getWritableDatabase();//執(zhí)行sql語(yǔ)句db4.update("user",values2,"id=?",new String[]{"1"});db4.close();}查詢(xún)數(shù)據(jù)
public void btnSelectData(View view) {//獲取數(shù)據(jù)庫(kù)對(duì)象DBHelper dbhelper5=new DBHelper(this,"test.db",null,2);SQLiteDatabase db5=dbhelper5.getWritableDatabase();//創(chuàng)建游標(biāo)對(duì)象Cursor cursor=db5.query("user",new String[]{"id","name"},"id=?",new String[]{"1"},null,null,null,null);//利用游標(biāo)遍歷所有數(shù)據(jù)對(duì)象while (cursor.moveToNext()){String name=cursor.getString(cursor.getColumnIndex("name"));Log.i("MainActivity","query-->"+name);}db5.close();}刪除數(shù)據(jù)
public void btnDelData(View view) {//獲取數(shù)據(jù)庫(kù)對(duì)象DBHelper dbhelper6=new DBHelper(this,"test.db",null,2);SQLiteDatabase db6=dbhelper6.getWritableDatabase();//刪除數(shù)據(jù)db6.delete("user","id=?",new String[]{"1"});db6.close();}總結(jié)
以上是生活随笔為你收集整理的005 Android之数据存储的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 004 Android之其他控件
- 下一篇: 006 Android之Activity