Android数据存储
时间:2022-04-24
本文章向大家介绍Android数据存储,主要内容包括数据存储、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
数据存储
Android
数据存储的几种形式
-
Internal Storage
Store private data on the device memory.
通过mContext.getFilesDir()
来得到data/data/包名/File
目录 -
External Storage
Store public data on the shared external storage.
TextView tv = (TextView) findViewById(R.id.tv_sdsize);
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
long sizeAvailSize = blockSize * availableBlocks;
String str = Formatter.formatFileSize(this, sizeAvailSize);
tv.setText(str);
-
SharedPreferences
Store private primitive data in key-value pairs.
会在data/data/包名/shared_prefes
里面去创建相应的xml
文件,根节点是Map
,其实内部就是将数据保存到Map
集合中, 然后将该集合中的数据写到xml
文件中进行保存。
<map>
<string name="password">123</string>
<boolean name="isLogin" value="false"/>
</map>
//获取系统的一个sharedpreference文件 名字叫sp
SharedPreferences sp = context.getSharedPreferences("sp", Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
//创建一个编辑器 可以编辑 sp
Editor editor = sp.edit();
editor.putString("name", name);
editor.putString("password", password);
editor.putBoolean("boolean", false);
editor.putInt("int", 8888);
editor.putFloat("float",3.14159f);
//注意:调用 commit 提交 数据到文件.
editor.commit();
//editor.clear();
-
SQLiteDatabase
Store structured data in a private database.
Android
平台中嵌入了一个关系型数据库SQLite
,和其他数据库不同的是SQLite
存储数据时不区分类型,例如一个字段声明为Integer
类型, 我们也可以将一个字符串存入, 一个字段声明为布尔型,我们也可以存入浮点数。除非是主键被定义为Integer
,这时只能存储64位整数创建数据库的表时可以不指定数据类型,例如:
CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))
CREATE TABLE person(id INTEGER PRIMARY KEY AUTOINCREMENT, name)
`SQLite`支持大部分标准`SQL`语句,增删改查语句都是通用的,分页查询语句和`MySQL`相同
SELECT * FROM person LIMIT 20 OFFSET 10
SELECT * FROM person LIMIT 10,20
SELECT * FROM reading_history ORDER BY _id DESC LIMIT 3, 4
DELETE FROM test WHERE _id IN (SELECT _id FROM test ORDER BY _id DESC LIMIT 3, 20)
`SQLite`数据库的使用 - 继承`SQLiteOpenHelper`
public class NoteSQLiteOpenHelper extends SQLiteOpenHelper {
/**
* name 数据库的名称 cursorfactory 游标工厂 一般设置null 默认游标工厂 version 数据库的版本
* 版本号从1开始的
*
* @param context
*/
public NoteSQLiteOpenHelper(Context context) {
super(context, "note.db", null, 1);
}
/**
* oncreate 方法 会在数据库第一创建的时候的是被调用 适合做数据库表结构的初始化
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table account (id integer primary key autoincrement , name varchar(20), money varchar(20) )");
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS " + account);
this.onCreate(db);
}
}
- 获取
public class NoteDao {
private NoteSQLiteOpenHelper helper;
public NoteDao(Context context) {
helper = new NoteSQLiteOpenHelper(context);
}
/**
* 添加一条账目信息 到数据库
*
* @param name
* 花销的名称
* @param money
* 金额
*/
public void add(String name, float money) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("insert into account (name,money) values (?,?)",
new Object[] { name, money });
// 记住 关闭.
db.close();
}
public void delete(int id) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("delete from account where id=?", new Object[] { id });
db.close();
}
public void update(int id, float newmoney) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("update account set money =? where id=?", new Object[] {
newmoney, id });
db.close();
}
/**
* 返回数据库所有的条目
*
* @return
*/
public List<NoteBean> findAll() {
// 得到可读的数据库
SQLiteDatabase db = helper.getReadableDatabase();
List<NoteBean> noteBeans = new ArrayList<NoteBean>();
// 获取到数据库查询的结果游标
Cursor cursor = db.rawQuery("select id,money,name from account ", null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
float money = cursor.getFloat(cursor.getColumnIndex("money"));
NoteBean bean = new NoteBean(id, money, name);
noteBeans.add(bean);
bean = null;
}
db.close();
return noteBeans;
}
/**
* 模拟一个转账的操作. 使用数据库的事务
*
* @throws Exception
*/
public void testTransaction() throws Exception {
// 得到可写的数据库
SQLiteDatabase db = helper.getWritableDatabase();
db.beginTransaction(); // 开始事务
try {
db.execSQL("update account set money = money - 5 where id=? ",
new String[] { "2" });
db.execSQL("update account set money = money + 5 where id=? ",
new String[] { "3" });
db.setTransactionSuccessful();
} catch (Exception e) {
// TODO: handle exception
} finally {
db.endTransaction();//关闭事务.
db.close();
}
}
}
public class NoteDao2 {
private NoteSQLiteOpenHelper helper;
public NoteDao2(Context context) {
helper = new NoteSQLiteOpenHelper(context);
}
/**
* 添加一条账目信息 到数据库
*
* @param name
* 花销的名称
* @param money
* 金额
*
* @return true 插入成功 false 失败
*/
public boolean add(String name, float money) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("money", money);
long rawid = db.insert("account", null, values);
db.close();
if (rawid > 0) {
return true;
} else {
return false;
}
}
public boolean delete(int id) {
SQLiteDatabase db = helper.getWritableDatabase();
int result = db.delete("account", "id=?", new String[] { id + "" });
db.close();
if (result > 0) {
return true;
} else {
return false;
}
}
public boolean update(int id, float newmoney) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("id", id);
values.put("money", newmoney);
int result = db.update("account", values, "id=?", new String[] { id
+ "" });
db.close();
if (result > 0) {
return true;
} else {
return false;
}
}
/**
* 返回数据库所有的条目
*
* @return
*/
public List<NoteBean> findAll() {
// 得到可读的数据库
SQLiteDatabase db = helper.getReadableDatabase();
List<NoteBean> noteBeans = new ArrayList<NoteBean>();
Cursor cursor = db.query("account", new String[] { "id", "name",
"money" }, null, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
float money = cursor.getFloat(cursor.getColumnIndex("money"));
NoteBean bean = new NoteBean(id, money, name);
noteBeans.add(bean);
bean = null;
}
db.close();
return noteBeans;
}
}
-
Network
Store data on the web with your own network server.
-
/data/data/包名
下的apk在安装时提示解析失败。 我们在更新或安装apk
时一般将其放到外部存储设备中来进行安装,但是如果一个手机没有外部存储设备该怎么办呢?总不能就不给更新或者安装了。 可能你会觉得很简单啊,我用mContext.getCacheDir()
或者mContext.getFilesDir()
等获取内部路径,把apk
放到这里面进行安装,但是你会发现安装 不了,提示解析失败。 这是为什么呢?其实是权限的问题。安装应用的app
是没有权限获取你应用的内部存储文件的,所以才会安装不上,那该怎么解决呢? 答案就是修改权限。
try {
InputStream is = getAssets().open(fileName);
File file;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
file = new File(Environment.getExternalStorageDirectory()
+ File.separator + fileName);
} else {
file = new File(mContext.getFilesDir()
+ File.separator + fileName);
String cmd = "chmod 777 " + file.getPath();
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] temp = new byte[1024];
int i = 0;
while ((i = is.read(temp)) > 0) {
fos.write(temp, 0, i);
}
fos.close();
is.close();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + file),
"application/vnd.android.package-archive");
startActivity(intent);
} catch (Exception e) {
LogUtil.e("@@@", e.toString());
e.printStackTrace();
}
3. 清除缓存&清除数据
清除数据会清除/data/data/
包名中的所有文件
清楚缓存会清楚getCacheDir()
目录下的内容,也就是/data/data/<当前应用程序包名>/cache/
- 论Go语言中goroutine的使用
- WordPress发布文章同步到新浪微博失败的问题解决与分享
- 压测工具swingbench和sysbench对比(r12笔记第13天)
- 解决WordPress4.4.1不支持图片暗箱问题,Begin主题适用
- MySQL源码安装总结(r12笔记第12天)
- 全站启用SSL之后,如何兼容不支持https抓取的搜索引擎?
- sandbox和MHA快速测试(r12笔记第32天)
- 分享一个支持https的CDN及启用SSL后续问题汇总
- 分分钟搭建MySQL一主多从环境(r12笔记第31天)
- 相同update语句在MySQL,Oracle的不同表现(r12笔记第30天)
- 升级Nginx1.9.5以上版本,开启博客网站http2.0时代
- Oracle Data Guard压缩归档测试(二)(r12笔记第27天)
- Oracle Data Guard压缩归档效果对比(r12笔记第26天)
- PHP7.0正式版编译安装升级及WordPress问题解决分享
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 什么?一个核同时执行两个线程?
- 如何下载网页上的视频?
- c++ int,unsigned int混合表达式类型转换
- MySQL5.7+查看Waiting for table metadata lock 锁情况
- input如何快速进行规则校验
- 史上最详细的sqlServer手工注入详解
- Spring 基于 Java 的配置
- Spring中的Spring JSR-250 注释之@Resource
- python 用opencv接口把视频逐帧转化为图片
- Element el-tree树形控件的数据处理方法
- 基于docker快速搭建hive环境
- flag区分大小写的sql盲注
- Spring中的Spring JSR-250 注释
- WebRTC 入门指南
- 【DB笔试面试844】在Oracle中,tnsnames.ora文件的作用是什么?