Android的数据存储

基础知识

基础知识来自《Android组件化架构》仓王著 一书。

Android的数据存储方式有哪些?

Android的5中存储方式:
· SharedPreferences(配置共享)
· File I/O(文件存储):内存和外部存储
· SQLite(数据库):数据库操作,数据库增删改查
· ContentProvider(内容提供者):用于跨进程数据共享,进程间通信
· 网络存储:上传数据和网络请求数据

数据存储的三个维度
存储方式安全效率量级
网络存储丢包、拦截问题写入和读取网络环境速度无限大
File I/Osd 内存存储大型数据文件SD卡内存
SQLiteApp内管理数据处理最高效,不用于保存大数据文件数据表格
ContentProviderApp外标识符分辨跨App传输数据,速度取决于存储数据的获取的类型和大小取决于存储体
SharedPreferencesApp内配置存储,并非专业用于数据持久化存储配置XML

安全、效率、量级决定我们使用哪种存储方式。

安全上
SQLite > SharedPreferences > ContentProvider > File I/O > 网络存储

SQLite的安全性最高,除了ContentProvider和本App,没有其他访问方式。持有相同的ShareUid、SharedPreferences可以被访问。ContentProvider是只要持有相同的标识符就能共享数据。而File I/O保存在App内,只要知道App内路径就能查看到。网络存储的安全性是最低的。

效率上
SQLite > SharedPreferences = File I/O > ContentProvider > 网络存储

量级上
网络存储 > File I/O > ContentProvider = SQLite > SharedPreferences


五种存储方式的基本原理

网络存储
使用HTTP协议或者Socket通信作为传输方式。(HTTP底层也是通过短时间的Socket通信来实现的传输)。我们通过目前流行的网络框架(如OkHttp、retrofit、volley等)来发送接收数据。其数据格式一般为XML、JSON格式。

File I/O
操作数据通过字节流操作来完成,直接对二进制数据进行处理。

SQLite
SQLite是轻量级数据库。通过SQLiteOpenHelper来封装入口,然后调用SQLiteDataBase进行操作。

ContentProvider
ContentProvider可以用于不同的应用程序共享数据,其数据的暴露方式是采取类似数据库中表的方法。而ContentResolver恰好采用类似数据库的方法从Content Provider中存取数据,它通过Uri的来查询ContentProvider中提供的数据。

SharedPreferences
SharedPreferences是一种轻量级的数据存储方式,它将一些简单数据类型的数据,包括boolean、int、float、long和String类型的数据,以键值对的形式存储在应用程序的私有SharedPreferences目录(/data/data/<包名>/shared_prefs/)中。通过将键值以XML格式保存到私有的XML文件中。


greenDao

简介

greenDao是一个热门的ORM(Object Relational Mapping,对象关系映射)数据库框架。greenDao能够提供一个接口,通过操作对象的方式去操作关系型数据库,操作数据库更简单、更方便。底层通过操作SQLiteDatebase来完成数据库操作。

greenDao create

greenDao是目前众多ORM数据库中最稳定、速度最快、编写体验最好的框架,并且支持RxJava。

greenDao的优点:

  • 性能高,号称Android最快的关系型数据库。
  • 内存占用小。
  • 库文件比较小,小于100KB,编译时间短,而且可以避免65K方法数限制。
  • 支持数据库加密,greenDao支持SQLCipher进行数据库加密。
  • 简洁易用的API。
greenDao的使用
  • gradle配置
// In your root build.gradle file:
buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
    }
}


// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
 
dependencies {
    implementation 'org.greenrobot:greendao:3.2.2' // add library
}

如果有新版本,将上面的版本号(3.2.2)替换。

  • 实体类

我们简单的使用三个注解:
    @Entity 声明实体对象;
    @Id 声明索引Id;
    @Property 声明每个对象带有的列名(columnName),默认为@Property(nameInDb = “name”)。
如下代码

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
import org.greenrobot.greendao.annotation.Generated;

@Entity
public class User {
    @Id
    @Property(nameInDb = "_id")
    private Long id;
    @Property(nameInDb = "name")
    private String name;
    @Property(nameInDb = "sex")
    private String sex;
    @Property(nameInDb = "age")
    private int age;
}

第一次编译会生成DaoMaster、DaoSession和数据类名Dao(如上代码即UserDao)文件。(第一次编译Bean里没有setter/getter方法,会自动生成)

可在下面路径中找到生成的DaoMaster、DaoSession和数据类名Dao。

app\build\generated\source\greendao\<包名>\<实体类所在包名>\

  • 初始化
//do this once, for example in your Application class
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, dbName, null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
DaoSession daoSession = daoMaster.newSession();

//do this in your activities/fragments to get hold of a DAO (Data Access Object 数据访问对象)
//通过DaoSession获得具体的DAO
daoSession.getUserDao();
  • 使用
//通过DaoSession获得具体的DAO
UserDao mUserDao = daoSession.getUserDao();
//插入数据
mUserDao.insert(new User(1L, "张三", "男", 23));
mUserDao.insert(new User(2L, "张三", "男", 26));
mUserDao.insert(new User(3L, "王五", "男", 13));
//查询数据
//User user = mUserDao.queryBuilder().where(UserDao.Properties.Name.eq("张三")).unique();
//Log.i(TAG, "queried user: " + user.toString());
List<User> list = mUserDao.queryBuilder().where(UserDao.Properties.Name.eq("张三")).list();
for (User user : list) {
    Log.i(TAG, "queried user: " + user.toString());
}

代码中的Name类型是Property,它封装一些条件函数,返回WhereCondition(where条件),非常的简单易用。
下面是Property的源码:

package org.greenrobot.greendao;

import java.util.Collection;

import org.greenrobot.greendao.internal.SqlUtils;
import org.greenrobot.greendao.query.WhereCondition;
import org.greenrobot.greendao.query.WhereCondition.PropertyCondition;

/**
 * Meta data describing a property mapped to a database column; used to create WhereCondition object used by the query builder.
 * 
 * @author Markus
 */
public class Property {
    public final int ordinal;
    public final Class<?> type;
    public final String name;
    public final boolean primaryKey;
    public final String columnName;

    public Property(int ordinal, Class<?> type, String name, boolean primaryKey, String columnName) {
        this.ordinal = ordinal;
        this.type = type;
        this.name = name;
        this.primaryKey = primaryKey;
        this.columnName = columnName;
    }

    /** Creates an "equal ('=')" condition  for this property. */
    public WhereCondition eq(Object value) {
        return new PropertyCondition(this, "=?", value);
    }

    /** Creates an "not equal ('<>')" condition  for this property. */
    public WhereCondition notEq(Object value) {
        return new PropertyCondition(this, "<>?", value);
    }

    /** Creates an "LIKE" condition  for this property. */
    public WhereCondition like(String value) {
        return new PropertyCondition(this, " LIKE ?", value);
    }

    /** Creates an "BETWEEN ... AND ..." condition  for this property. */
    public WhereCondition between(Object value1, Object value2) {
        Object[] values = { value1, value2 };
        return new PropertyCondition(this, " BETWEEN ? AND ?", values);
    }

    /** Creates an "IN (..., ..., ...)" condition  for this property. */
    public WhereCondition in(Object... inValues) {
        StringBuilder condition = new StringBuilder(" IN (");
        SqlUtils.appendPlaceholders(condition, inValues.length).append(')');
        return new PropertyCondition(this, condition.toString(), inValues);
    }

    /** Creates an "IN (..., ..., ...)" condition  for this property. */
    public WhereCondition in(Collection<?> inValues) {
        return in(inValues.toArray());
    }

    /** Creates an "NOT IN (..., ..., ...)" condition  for this property. */
    public WhereCondition notIn(Object... notInValues) {
        StringBuilder condition = new StringBuilder(" NOT IN (");
        SqlUtils.appendPlaceholders(condition, notInValues.length).append(')');
        return new PropertyCondition(this, condition.toString(), notInValues);
    }

    /** Creates an "NOT IN (..., ..., ...)" condition  for this property. */
    public WhereCondition notIn(Collection<?> notInValues) {
        return notIn(notInValues.toArray());
    }

    /** Creates an "greater than ('>')" condition  for this property. */
    public WhereCondition gt(Object value) {
        return new PropertyCondition(this, ">?", value);
    }

    /** Creates an "less than ('<')" condition  for this property. */
    public WhereCondition lt(Object value) {
        return new PropertyCondition(this, "<?", value);
    }

    /** Creates an "greater or equal ('>=')" condition  for this property. */
    public WhereCondition ge(Object value) {
        return new PropertyCondition(this, ">=?", value);
    }

    /** Creates an "less or equal ('<=')" condition  for this property. */
    public WhereCondition le(Object value) {
        return new PropertyCondition(this, "<=?", value);
    }

    /** Creates an "IS NULL" condition  for this property. */
    public WhereCondition isNull() {
        return new PropertyCondition(this, " IS NULL");
    }

    /** Creates an "IS NOT NULL" condition  for this property. */
    public WhereCondition isNotNull() {
        return new PropertyCondition(this, " IS NOT NULL");
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验报告封面 课程名称: Android平台开发与应用 课程代码: SM3004 任课老师: 梁郁君 实验指导老师: 梁郁君 实验报告名称:实验10 Android数据存储与IO 学生姓名: 学号: 教学班: 递交日期: 签收人: 我申明,本报告内的实验已按要求完成,报告完全是由我个人完成,并没有抄袭行 为。我已经保留了这份实验报告的副本。 申明人(签名): 实验报告评语与评分: 评阅老师签名: 一、实验名称:Android数据存储与IO 二、实验日期:2014/11/13 三、实验目的: 1、掌握SharedPreferences的存储数据的格式及位置,能够读写其他应用程序的Shared Preferences。 2、File存储数据 3、掌握SQLite存储数据方法。 4、会使用SQLiteOpenHelper辅助类,进行操作数据库。 四、实验用的仪器和材料: PC+Eclipse+ADT 五、实验的步骤和方法: 1、读写其他应用程序SharedPreferences。 读写其他应用程序的SharedPreferences,步骤如下: 创建应用App1 和应用App2,App2尝试读取App1的SharedPreferences内容 在App2 需要创建App1对应的Context。 调用App1的Context的getSharedPreferences(String name,int mode) 即可获取相应的SharedPreferences对象。 如果需要向App1的SharedPreferences数据写入数据,调用SharedPreferences的e dit()方法获取相应的Editor即可。 根据上述说明和下面截图,以及代码注释,完成相关代码片段填空,并思考问题: SharedPreferences何时会丢失? 图1 App1运行的界面 图2 App2 运行结果 App1:记录应用程序的使用次数,/com.Test/UseCount.java程序如下,补充程序中所缺 代码: "import android.app.Activity; " "import android.content.SharedPreferences; " "import android.content.SharedPreferences.Editor; " "import android.os.Bundle; " "import android.widget.Toast; " "public class UseCount extends Activity{ " "SharedPreferences preferences; " "@Override " "public void onCreate(Bundle savedInstanceState){ " "super.onCreate(savedInstanceState); " "setContentView(R.layout.main); " "preferences = getSharedPreferences("count", MODE_WORLD_READABLE); " "//读取SharedPreferences里的count数据 " "int count = ("count" , 0); " "//显示程序以前使用的次数 " "Toast.makeText(this , "程序以前被使用了" + count + "次。", " "10000).show(); " "Editor editor = ; " "//存入数据 " "editor.putInt("count" , ++count); " "//提交修改 " "editor. ; " "} " "} " App2:ReadOtherPreferences.java代码如下,补充程序所缺代码: "import android.app.Activity; " "import android.content.Context; " "import android.content.SharedPreferences; " "import " "android.content.pm.PackageManager.NameNotFoundException; " "import android.os.Bundle; " "import android.widget.TextView; " "public class ReadOtherPreferences extends Activity{ " "Context useCount; " "@Override " "public void onCreate(Bundle sav

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值