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