Android資料存放區,android資料存放區方式

來源:互聯網
上載者:User

Android資料存放區,android資料存放區方式
SharedPreferences與Editor

SharedPreferences儲存的資料只要是類似於配置資訊格式的資料,因此它儲存的資料主要是簡單的key-value對形式。下面關係圖


完全可以看出,存的時候用SharedPreferences的內部類Editor,取的時候用SharedPreferences。

SharedPreference是介面無法建立執行個體,Context提供下面方法建立執行個體 該執行個體只能有一個,也就是單例模式。

getSharedPreferences(String name,int mode);


存取例子

 public class MainActivity extends Activity { SharedPreferences sp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//擷取SharedPreferences執行個體  Test是檔案名稱,不要加尾碼,預設為XML格式sp = getSharedPreferences("Test", Context.MODE_WORLD_WRITEABLE);//得到內部類寫資料SharedPreferences.Editor editor = sp.edit();editor.putString("name", "value");//不提交則無法獲得資料editor.commit();}public void btn(View view){String string = sp.getString("name", "null");Toast.makeText(this, string, 1).show();}}
儲存路徑為:data/data/包名/shared_prefs/Test.xml

開啟該檔案看到

<?xml version="1.0" encoding="utf-8" standalone ="yes" ?><map><string name="name">value</string></map>

儲存的放值的時候String對應XML檔案裡就是string節點,Int的時候對應int節點。

儲存時間長度:卸載軟體時包名所在的檔案夾會消失,所以該檔案無法同樣會消失。


讀寫其他應用的SharedPreferences

上述是在本身的APP中玩耍,這次看如何讀取其他應用,關鍵是獲得其他應用的程式的Context(代表Android應用的全域資訊的介面)又因為包名是Andoird應用的唯一標示,所以調用本APP的Context的方法

createPackageContext("android.example.homework", CONTEXT_IGNORE_SECURITY);

得到其他應用的Context對象並且其他應用SharedPreferences是可讀狀態(可寫不行,必須可讀)後就可以“為所欲為”了。

public class MainActivity extends Activity {SharedPreferences sp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 擷取SharedPreferences執行個體try {//通過包名得到該應用的Context對象Context context=createPackageContext("com.example.homework", CONTEXT_IGNORE_SECURITY);//用其他應用的Context建立SharedPreferencessp = context.getSharedPreferences("Test", Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);} catch (NameNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void btn(View view) {String string = sp.getString("name", "null");Toast.makeText(this, string, 1).show();}}

上述的讀寫並不是唯一的,程式員完全可以利用IO流來直接操作本應用和其他應用的SharedPreferences資料,只是Android將他封裝好了,很簡便。

無法儲存自訂類型,主要儲存的APP配置資訊,例如(使用者名稱,密碼等)。

Chche儲存

儲存空間不夠系統會刪除Cache儲存,但不要依賴系統刪除

存:

File dir = getCacheDir();File file = new File(dir,"test.txt");try {FileOutputStream fos = new FileOutputStream(file);fos.write("緩衝儲存".getBytes());} catch (Exception e) {// TODO: handle exception}

取:

FileInputStream fis = new FileInputStream(file)

以上兩種方式均為內部儲存,卸載應用時資料都會丟失。


File儲存

FIle儲存就是Android繼續使用Java中的IO流繼續讀寫檔案的一種方式

兩個核心方法:

openFileInput(String name);

openFIleOutput(String name);

下面是簡單讀寫的例子

public class MainActivity extends Activity {SharedPreferences sp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void readed(View view) {FileInputStream fis = null;StringBuffer sb=null;try {//開啟檔案輸入資料流     files檔案名稱,這裡系統不給添加尾碼,不寫無尾碼fis = openFileInput("files");byte[] buff = new byte[1024];int len = 0;sb = new StringBuffer();while ((len = fis.read(buff)) != -1) {sb.append(new String(buff, 0, len));}//關流fis.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}Toast.makeText(this, sb, 0).show();}public void writer(View view) {FileOutputStream fos = null;try {// 以追加模式開啟檔案輸出資料流fos = openFileOutput("files", MODE_APPEND);// 將流封裝成PrintStreamPrintStream printStream = new PrintStream(fos);printStream.print("內容啦啦啦啦");Toast.makeText(this, "寫入成功", 0).show();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {if (fos != null)try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

該檔案無尾碼,系統預設不添加尾碼,存放路徑為data/data/包名/file/檔案夾下

該檔案依然存放在包名下,所以卸載時依然會遺失資料。


SD卡儲存

使用File儲存和SharedPreferences儲存的缺點是容量小,因為在應用程式的資料檔案夾下。所以才有了SD卡儲存。使用SD卡儲存總共分為三步:

(1)判斷應用是否有讀寫SD卡許可權

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
(2)獲得SD卡的目錄

File dir = Environment.getExternalStorageDirectory();
(3)使用流讀寫資料


SD卡的許可權

<!-- 添加SD卡的建立與刪除檔案許可權 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 添加SD卡寫入許可權 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

讀寫SD卡例子

public class MainActivity extends Activity {private final String FILE_NAME="test.txt";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}/**讀取資料*/public void readed(View view) {BufferedReader bis=null;//當SD狀態裝備就緒時if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){File dir = Environment.getExternalStorageDirectory();try {File file = new File(dir, FILE_NAME);FileInputStream fis = new FileInputStream(file);//將fis流封裝成BufferedReaderbis= new BufferedReader(new InputStreamReader(fis));String len = null;StringBuffer sb = new StringBuffer("");while((len=bis.readLine())!=null){sb.append(len);}Toast.makeText(this, "讀到的資料是:"+sb, 0).show();} catch (Exception e) {e.printStackTrace();} finally{if(bis!=null){try {bis.close();} catch (IOException e) {e.printStackTrace();}}}}else Toast.makeText(this, "SD卡不可用", 0).show();}/**寫入資料*/public void writer(View view) {RandomAccessFile raf = null;if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){File dir = Environment.getExternalStorageDirectory();File file = new File(dir, FILE_NAME);//用指定檔案建立RandomAccessFIletry {raf = new RandomAccessFile(file, "rw");//將檔案記錄指標移動到最後  防止再次寫入覆蓋之前的raf.seek(file.length()); raf.write("來一個字串玩玩".getBytes());Toast.makeText(this, "寫入成功", 0).show();} catch (Exception e) {e.printStackTrace();}finally{if(raf!=null){try {raf.close();} catch (IOException e) {e.printStackTrace();}}}}}}

SQLite儲存

SQLite是輕量級的資料庫(底層就是一個資料庫檔案)一旦應用獲得了代表指定資料庫的SQLiteDatabase對象,接下來就可以通過該對象來管理,操作資料庫了。

(1)擷取SQLiteDatabase對象,它代表了與資料庫的連結。

(2).調用SQLiteDatabase的方法來執行SQL語句。

(3).操作SQL語句的執行結果,比如用SimpleCursorAdapter封裝Cursor

(4).關閉SQLiDatabase,回收資源。

常用方法

//建立(如果不存在)或開啟資料庫static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory)
//打卡一個已經存在的資料庫static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags)

MainActivity.java

public class MainActivity extends Activity {private ListView listview;private SQLiteDatabase db;private EditText editText;private String TABLE_NAME="student";//建立表語句private String CREATE_TABLE = "create table "+TABLE_NAME+" (_id integer primary key autoincrement,name varchar(20),age integer)";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化editText = (EditText) findViewById(R.id.et);listview=(ListView) findViewById(R.id.listivew);//開啟或建立資料庫(這裡需要絕對路徑)db=SQLiteDatabase.openOrCreateDatabase("/mnt/sdcard/my.db3", null);if(!exits(TABLE_NAME)){db.execSQL(CREATE_TABLE);}}@Overrideprotected void onDestroy() {super.onDestroy();//關閉資料庫if(db!=null&&db.isOpen())db.close();}public void btn(View view){switch (view.getId()) {case R.id.btn1://插入String str = editText.getText().toString();String sql = "insert into "+TABLE_NAME+" (name) values ('"+str+"') ";System.out.println(sql);db.execSQL(sql);break;case R.id.btn2://讀取String sql2 = "select * from "+TABLE_NAME+"";Cursor cursor = db.rawQuery(sql2, null);inflateListView(cursor);break;}}public boolean exits(String table){String sql= "select * from sqlite_master where name="+"'"+table+"'";System.out.println(sql);Cursor cursor = db.rawQuery(sql, null);if(cursor.getCount()!=0){return true;}return false;}private void inflateListView(Cursor cursor){//構建Cursor適配器的同時就是對Cursor封裝成為AdapterSimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{"name"}, new int[]{android.R.id.text1},CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);listview.setAdapter(adapter);}}


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <EditText        android:id="@+id/et"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    <Button        android:id="@+id/btn1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="btn"        android:text="插入 字串資料" />    <Button        android:id="@+id/btn2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:onClick="btn"        android:text="取出資料" />    <ListView        android:id="@+id/listivew"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    </ListView></LinearLayout>


由於是自訂的路徑,所以卸載軟體依然存在。這種直接使用SQLiteDatabase的方式使用的極少的。

注意:這裡主鍵的列名必須為_id,因為SimpleCursorAdapter只能識別列名為_id的主鍵。


SQLiteOpenHelper

這種繼承SQLiteOpenHelper方式用的還是比較多的。它是Android提供的一個管理資料庫的工具類,可用於管理資料庫的建立的版本和更新。

常用方法:

synchronized SQLiteDatabase getReadableDatabase();以唯讀方式開啟對應SQLiteDatabase 對象

synchronized SQLiteDatabase getWritableDatabase();以寫方式開啟對應SQLiteDatabase 對象

abstract void Create(SQLiteDatabase db);第一次建立資料庫時回調該方法。

abstract void Upgrade(SQLiteDatabase db,int oldVersion,int newVersion);當資料庫版本更新時回調該方法。

在獲得資料庫執行個體時建議使用getReadableDatabase();如果用getWritableDatabase()一旦磁碟滿了,開啟資料庫就會出錯,而getReadableDatabase方法先唯讀方式開啟,就算磁碟空間滿了,也不會出錯,而是繼續使用唯讀方式。(getReadableDatabase調用時會包含getWritableDatabase)當調用getReadableDatabase()如果資料庫不存在調用onCreate(SQLiteDatabase db);存在之後返回該執行個體

MyDB.java

public class MyDB extends SQLiteOpenHelper {//參數1:上下文//參數2:資料庫名字//參數3:遊標工廠(自訂的時候才用,不需要自訂null)//資料庫版本號碼public MyDB(Context context, String name,  int version) {super(context, name, null, version);// TODO Auto-generated constructor stub}public SQLiteDatabase db;final String CREATE_TABLE="create table student(_id integer primary key autoincrement,word varchar(20),detail varchar(20))";//第一次建立資料庫的時候調用,當運行第二次時db==null@Overridepublic void onCreate(SQLiteDatabase db) {this.db=db;db.execSQL(CREATE_TABLE);}//軟體升級的時候更新表結構調用,當newVersion>oldVersion時,系統自動觸發該方法。@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}



MainActivity.java

public class MainActivity extends Activity {String a;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyDB db = new MyDB(this, "mydb.db3", 1);SQLiteDatabase database = db.getReadableDatabase();}}

儲存路徑data/data/包名/databases/mydb.db3

卸載時檔案依然丟失。


查詢的時候會用到Cursor:

常用方法:

isAfterLast()遊標的指標是否指向了最後一條資料的後面

moveToNext() 讓遊標的指標指向下一條資料

moveToFirst() 讓遊標的指標指向第一條資料

getString(int columnIndex) 擷取當前行中指定列的String值,參數列索引

getColumnIndex(StringcolumnName) 根據列名字擷取列索引

插入會用到:ContentValus 

ContentValus的方法很簡單,鍵值對而已

修改資料:

//修改   參數1:被修改的表的名字   參數2:修改的成為的值    參數3:更新條件   參數4:更新條件中預留位置的值

db.update(DBHelper.TABLE_NAME, values,DBHelper.ENSCORE_NAME+" = ?", new String[]{"hanhan"});

 刪除資料:

//資料刪除  參數1:要刪除資料的表的名字   參數2:刪除條件    參數3:刪除條件中的預留位置的值

        //返回值---》刪除資料的行數

db.delete(DBHelper.TABLE_NAME,DBHelper.ENSCORE_NAME+" = ?", new String[]{"zhangsan"});






著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.