现在大数据的时代,数据在咱们生活中扮演的角色愈来愈重要了,咱们使用的手机产生的大量数据,很好的反应了咱们的生活习惯、做息规律、兴趣爱好等。接下来咱们就来小谈一下 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详解
网络存储就是调用接口获得返回值进行数据展现