現在大數據的時代,數據在咱們生活中扮演的角色愈來愈重要了,咱們使用的手機產生的大量數據,很好的反應了咱們的生活習慣、做息規律、興趣愛好等。接下來咱們就來小談一下 Android 中的數據存儲的五種方式。java
-Filegithub
-SQLitesql
-ContentProvider數據庫
-網絡存儲bash
SharedPreferences 用於保存少許、數據格式簡單(字符串、基本類型)的數據,例如:App 的配置信息,鎖屏密碼等。保存基於 XML 文件存儲的 key-value 鍵值對數據,一般用來存儲一些簡單的配置信息。經過 DDMS 的 File Explorer 面板,展開文件瀏覽樹,很明顯 SharedPreferences 數據老是存儲在/data/data//shared_prefs 目錄下網絡
Context.MODE_PRIVATE: 指定該 SharedPreferences 數據只能被本應用程序讀、寫。 Context.MODE_WORLD_READABLE: 指定該 SharedPreferences 數據能被其餘應用程序讀,但不能寫。 Context.MODE_WORLD_WRITEABLE: 指定該 SharedPreferences 數據能被其餘應用程序讀,寫app
主要方法: Editor putXXX(String key, @Nullable XXX value);//存入指定 key 的各類基本類型的數據 Editor remove(String key);//刪除指定 key 的數據 Editor clear();//清空全部數據 boolean commit();//提交數據 void apply();//提交數據異步
注:SharedPreference 相關修改使用 apply 方法進行提交會先寫入內存,而後異步寫入磁盤,commit 方法是直接寫入磁盤。若是頻繁操做的話 apply 的性能會優於 commit,apply 會將最後修改內容寫入磁盤。 可是若是但願馬上獲取存儲操做的結果,並據此作相應的其餘操做,應當使用 commit。ide
存儲數據:
//建立一個 SharedPreferences.Editor 接口對象,madreain 表示要寫入的 XML 文件名,MODE_PRIVATE 讀寫操做
SharedPreferences.Editor editor = getSharedPreferences("madreain", MODE_PRIVATE).edit();
//將值放入文件
editor.putString("test", "存儲的值");
editor.apply();
複製代碼
獲取數據
SharedPreferences.Editor editor = getSharedPreferences("madreain", MODE_PRIVATE).edit();
String value = editor.getString("test");
複製代碼
通常這裏都會封裝 SharedPreference 的工具類,可參考SPUtils
Context 提供了兩個方法來打開數據文件裏的文件 IO 流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),這兩個方法第一個參數 用於指定文件名,第二個參數指定打開文件的模式。
打開文件的模式有如下幾種: MODE_PRIVATE:爲默認操做模式,表明該文件是私有數據,只能被應用自己訪問,在該模式下,寫入的內容會覆蓋原文件的內容。 MODE_APPEND:模式會檢查文件是否存在,存在就往文件追加內容,不然就建立新文件。 MODE_WORLD_READABLE:表示當前文件能夠被其餘應用讀取; MODE_WORLD_WRITEABLE:表示當前文件能夠被其餘應用寫入。
Context 其餘重要的相關方法: getDir(String name , int mode):在應用程序的數據文件夾下獲取或者建立 name 對應的子目錄 File getFilesDir():獲取該應用程序的數據文件夾得絕對路徑 String[] fileList():返回該應用數據文件夾的所有文件
讀取文件相關代碼
public String read() {
try {
FileInputStream fileInputStream = openFileInput("madreain.txt");
byte[] buffer = new byte[1024];
int hasRead = 0;
StringBuilder sb = new StringBuilder();
while ((hasRead = fileInputStream.read(buffer)) != -1) {
sb.append(new String(buffer, 0, hasRead));
}
fileInputStream.close();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
複製代碼
寫入文件相關代碼
public void write(String msg){
if(msg == null) return;
try {
FileOutputStream fileOutputStream = openFileOutput("madreain.txt",MODE_APPEND);
fileOutputStream.write(msg.getBytes());
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
複製代碼
⚠️ 注意: openFileOutput()方法的第一參數用於指定文件名稱,不能包含路徑分隔符「/」 ,若是文件不存在,Android 會自動建立它。建立的文件保存在/data/data//files 目錄,如: /data/data/com.madreain.app/files/madreain.txt。 com.madreain.app 這裏是包名
sdcard 上的文件操做: 1.SD 卡的權限(模擬器:可經過 mksdcard 命令來建立虛擬存儲卡)
2.調用 Environment 的 getExternalStorageState()方法判斷手機上是否插了 sd 卡,且應用程序具備讀寫 SD 卡的權限,以下代碼將返回 true Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
3.調用 Environment.getExternalStorageDirectory()方法來獲取外部存儲器,也就是 SD 卡的目錄,或者使用"/mnt/sdcard/"目錄
4.使用 IO 流操做 SD 卡上的文件
讀取文件相關代碼
private String read() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ DIR
+ File.separator
+ FILENAME);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
Scanner scan = null;
StringBuilder sb = new StringBuilder();
try {
scan = new Scanner(new FileInputStream(file));
while (scan.hasNext()) {
sb.append(scan.next() + "\n");
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (scan != null) {
scan.close();
}
}
} else {
Toast.makeText(this, "讀取失敗,SD卡不存在!", Toast.LENGTH_LONG).show();
}
return null;
}
複製代碼
寫入文件相關代碼
private void write(String content) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ DIR
+ File.separator
+ FILENAME);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream(file, true));
out.println(content);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
} else {
Toast.makeText(this, "保存失敗,SD卡不存在!", Toast.LENGTH_LONG).show();
}
}
複製代碼
FileIO 的工具類,可參考FileIOUtils
SQLite 是輕量級嵌入式數據庫引擎,它支持 SQL 語言,而且只利用不多的內存就有很好的性能。如今的主流移動設備像 Android、IOS 等都使用 SQLite 做爲複雜數據的存儲引擎,在咱們爲移 動設備開發應用程序時,也許就要使用到 SQLite 來存儲咱們大量的數據,因此咱們就須要掌握移動設備上的 SQLite 開發技巧
通用方法
db.executeSQL(String sql);
db.executeSQL(String sql, Object[] bindArgs);//sql語句中使用佔位符,而後第二個參數是實際的參數集
複製代碼
增刪改查方法
db.insert(String table, String nullColumnHack, ContentValues values);
db.delete(String table, String whereClause, String whereArgs);
db.update(String table, Contentvalues values, String whereClause, String whereArgs);
db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);
複製代碼
執行數據庫的增刪改查操做前,咱們得建立數據庫類
public class SqliteDBHelper extends SQLiteOpenHelper {
//數據庫相關設置
private static final String DATABASE_NAME = "madreain_db";//數據庫名字
private static final int VERSION = 1;//數據庫版本號
private static final String TABLE_NAME = "note";//數據庫表名 可建立多個表
public SqliteDBHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
public SqliteDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
/**
* 數據庫第一次建立時調用
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
String strSQL = "create table " + TABLE_NAME + "(tid integer primary key autoincrement,title varchar(20),weather varchar(10),context text,publish date)";
db.execSQL(strSQL);
}
/**
* 數據庫版本號變化時調用
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
複製代碼
實際業務中,咱們會建立一個Dao來封裝咱們的業務方法
public class DiaryDao {
private SqliteDBHelper sqliteDBHelper;
private SQLiteDatabase db;
// 重寫構造方法
public DiaryDao(Context context) {
this.sqliteDBHelper = new SqliteDBHelper(context);
db = sqliteDBHelper.getWritableDatabase();
}
// 讀操做
public String execQuery(final String strSQL) {
try {
// Cursor至關於JDBC中的ResultSet
Cursor cursor = db.rawQuery(strSQL, null);
// 始終讓cursor指向數據庫表的第1行記錄
cursor.moveToFirst();
// 定義一個StringBuffer的對象,用於動態拼接字符串
StringBuffer sb = new StringBuffer();
// 循環遊標,若是不是最後一項記錄
while (!cursor.isAfterLast()) {
sb.append(cursor.getInt(0) + "/" + cursor.getString(1) + "/"
+ cursor.getString(2) + "/" + cursor.getString(3) + "/"
+ cursor.getString(4) + "#");
//cursor遊標移動
cursor.moveToNext();
}
db.close();
return sb.deleteCharAt(sb.length() - 1).toString();
} catch (RuntimeException e) {
e.printStackTrace();
return null;
}
}
// 寫操做
public boolean execOther(final String strSQL) {
db.beginTransaction(); //開始事務
try {
db.execSQL(strSQL);
db.setTransactionSuccessful(); //設置事務成功完成
db.close();
return true;
} catch (RuntimeException e) {
e.printStackTrace();
return false;
} finally {
db.endTransaction(); //結束事務
}
}
}
複製代碼
實際增刪改查操做
//建立數據庫
SqliteDBHelper sqliteDBHelper = new SqliteDBHelper(this);
sqliteDBHelper.getWritableDatabase();
//實例化
DiaryDao diaryDao = new DiaryDao(this);
// 增
String strSQL = "insert into diary values(null,'" + "標題1" + "','" + "天氣" + "','" + "文章" + "','" + "時間" + "')";
boolean flag = diaryDao.execOther(strSQL);
// 刪
strSQL = "delete from diary where tid = 1";
flag = diaryDao.execOther(strSQL);
// 改
strSQL = "select * from diary order by publish desc";
String data = diaryDao.execQuery(strSQL);
// 查
strSQL = "update diary set title = '標題1' where tid = 1";
flag = diaryDao.execOther(strSQL);
複製代碼
推薦一下經常使用的第三方數據庫:OrmLite、GreenDao、LitePal、Realm、Afinal (可按照本身的需求去選擇相對應的第三方數據庫)
Android查看數據庫工具推薦:stetho、Android-Debug-Database
ContentProvider相關使用參考ContentProvider詳解
網絡存儲就是調用接口獲得返回值進行數據展現