Android中的三种数据存储方式
目录
1.文件存储
1)内部存储
1--MODE_PRIVATE:
2--MODE_APPEND:
3--MODE_WORLD_READABLE:
4--MODE_WORLD_WRITEABLE:
5--简单使用
3)外部存储
4)内部读取
4)外部读取
1)基本概念
2)存储位置
3)支持的数据类型
4)使用步骤
2--编辑数据
3--读取数据
5)注意事项
3.SQLite数据存储
1)创建SQLite数据库
2)SQLite数据库的基本操作
1--新增操作
2--删除数据
3--修改数据
4--查询数据
3)SQLite数据库中的事务
1.文件存储
- 文件存储是指直接将数据以文件的形式保存到设备的内部或外部存储中。
- 内部存储通常是私有的,其他应用无法访问你的应用创建的文件,除非你明确地共享它们。
- 外部存储可以是公共的(比如SD卡),用户和其他应用都可以访问这些文件。
- 使用
openFileOutput()
和openFileInput()
等API来读写文件。 - 适用于存储大量文本数据或者二进制数据,如图片、视频等。
1)内部存储
1--MODE_PRIVATE:
该文件只能被但当前程序读写
2--MODE_APPEND:
该文件的内容可以追加
3--MODE_WORLD_READABLE:
该文件的内容可以被其他程序读
4--MODE_WORLD_WRITEABLE:
该文件的内容可以被其他程序写
//写入流
FileOutputStream fos = openFileOutput(String name , int mode)
//读取流
FileInputStream fis = openFileInput(String name);
5--简单使用
String 文件名字 = "名字" //文件名
String 数据名 = "这里是数据的内容" //需要保存的数据
FileOutputStream fos = null;
try{
fos = openFileOutput(文件名字,写入模式)
fos.write(数据名.getBytes());//将数据写入文件
}catch(Exception e){
e.printStackTrace();//打印错误信息
}
}finally{
try{
if(fos!=null){
fos.close(); //把输入流关闭
}
catch(Exception e){
e.printStackTrace();//打印错误信息
}
}
}
3)外部存储
//外部写入public void outRead(){//获取SD卡状态String SDStatus = Environment.getExternalStorageState();//判断卡片是否可用if (!SDStatus.equals(Environment.MEDIA_MOUNTED)) {return;}//获取SD卡路径File externalStorageDirectory = Environment.getExternalStorageDirectory();File file = new File(externalStorageDirectory,"data.txt");//创建写入流FileOutputStream fos = null;try {//写入流fos = new FileOutputStream(file);//写入内容fos.write("写入数据".getBytes());} catch (Exception e) {e.printStackTrace();}finally {try {fos.close();} catch (Exception e) {e.printStackTrace();}}}
4)内部读取
openFileInput()获取FileInputStream读取流fis===>读取流fis创建字节缓冲区===>fis.read()==>读取之后转化为字符串写入
//内部读取public void inRead(){String contextInfo = "";//读取流FileInputStream fis = null;try {//读取文件流fis = openFileInput("data.txt");byte[] bytes = new byte[fis.available()];//文件读取到bytes数组中fis.read(bytes);//将读取到的字节数组转换为字符串contextInfo = new String(bytes);} catch (Exception e) {e.printStackTrace();}finally {try {fis.close();} catch (Exception e) {e.printStackTrace();}}}
4)外部读取
//外部读取public void outReadTwo(){//SD状态 === 》 判断sd卡是否存在 ==》存在==>读取外部文件String SDStatus = Environment.getExternalStorageState();if (!SDStatus.equals(Environment.MEDIA_MOUNTED)){return;}//获取SD卡路径File externalStorageDirectory = Environment.getExternalStorageDirectory();File file = new File(externalStorageDirectory,"data.txt");//读取流FileInputStream fis = null;try {fis = new FileInputStream(file);byte[] bytes = new byte[fis.available()];fis.read(bytes);String contextInfo = new String(bytes);} catch (Exception e) {e.printStackTrace();}finally {try {fis.close();return;}catch (Exception e) {e.printStackTrace();}}}
2.SharePreferences存储
- SharedPreferences 是一种轻量级的数据存储方式,主要用于保存应用程序的配置信息,例如用户的设置偏好。
- 数据是以键值对(key-value)形式存储,并且是以XML文件格式存放在设备上。
- 使用
getSharedPreferences()
获取SharedPreferences对象,然后通过edit()
方法编辑数据,最后调用apply()
或commit()
保存更改。 - 适合于存储少量的原始类型数据,如布尔值、整数、浮点数、字符串等。
- 不适合存储复杂的数据结构或大量的数据。
1)基本概念
- SharedPreferences 对象:代表一个文件,其中包含了一些键值对。
- Editor:通过
SharedPreferences
的edit()
方法获取到的对象,用来修改数据。 - 键值对:数据的基本单位,由一个唯一的键和对应的值组成。
2)存储位置
SharedPreferences
文件默认存储在应用私有目录下的/data/data/<package_name>/shared_prefs/
目录中。- 用户无法直接访问这个目录,除非设备已 root 并且用户具有足够的权限。
3)支持的数据类型
boolean
float
int
long
String
Set<String>
4)使用步骤
1--获取 SharedPreferences 对象
// 获取名为 "MyPreferences" 的 SharedPreferences 对象
SharedPreferences sharedPreferences = getSharedPreferences("MyPreferences", MODE_PRIVATE);
2--编辑数据
// 获取 Editor 对象
SharedPreferences.Editor editor = sharedPreferences.edit();// 添加键值对
editor.putString("key_string", "Hello, World!");
editor.putInt("key_int", 42);
editor.putBoolean("key_boolean", true);// 提交更改
editor.apply(); // 异步操作,不阻塞主线程
// 或者使用 editor.commit(); // 同步操作,会阻塞主线程直到写入完成
- 通过
SharedPreferences.Editor
接口来编辑数据。 putXXX()
方法将键值对添加到编辑器中。apply()
或commit()
将更改提交到SharedPreferences
。
3--读取数据
// 读取数据
String value = sharedPreferences.getString("key_string", "Default Value");
int intValue = sharedPreferences.getInt("key_int", 0);
boolean boolValue = sharedPreferences.getBoolean("key_boolean", false);
- 通过
SharedPreferences
的getXXX()
方法读取数据。 - 如果没有找到指定的键,则可以提供一个默认值。
5)注意事项
- 线程安全:
SharedPreferences
不是线程安全的,如果在多线程环境中使用,需要自行处理同步问题。 - 性能:频繁地调用
apply()
或commit()
可能会导致性能问题,尽量减少不必要的写入操作。 - 安全性:虽然
SharedPreferences
是私有的,但并不适合存储敏感信息,如密码等,因为这些信息可能被反编译工具读取。
SharedPreferences
非常适合于存储少量、简单的数据,比如用户的设置选项。对于更复杂的数据结构或大量的数据,建议使用 SQLite 数据库或其他形式的持久化存储。
3.SQLite数据存储
- SQLite 是一个关系型数据库管理系统,它被嵌入到Android系统中,提供了强大的数据存储能力。
- 它支持SQL语言,允许开发者执行复杂的查询操作。
- 使用
SQLiteOpenHelper
类可以帮助管理数据库的创建和版本更新。 SQLiteDatabase
类用于进行数据库的操作,包括增删改查。- 适合存储结构化的数据,以及需要进行复杂查询的数据集。
- 可以处理大量数据,但相比其他两种方式,它的使用稍微复杂一些。
1)创建SQLite数据库
为了方便地管理SQLite数据库,通常会继承SQLiteOpenHelper
类,并重写其中的onCreate()
和onUpgrade()
方法。
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;public class DatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "example.db";private static final int DATABASE_VERSION = 1;// 表名public static final String TABLE_NAME = "users";// 列名public static final String COLUMN_ID = "_id";public static final String COLUMN_NAME = "name";public static final String COLUMN_AGE = "age";private static final String CREATE_TABLE ="CREATE TABLE " + TABLE_NAME + "(" +COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +COLUMN_NAME + " TEXT, " +COLUMN_AGE + " INTEGER" + ")";public DatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_TABLE); // 创建表}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 删除旧表并重新创建(简单处理)db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);onCreate(db);} }
2)SQLite数据库的基本操作
1--新增操作
public long insertUser(String name, int age) {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();ContentValues values = new ContentValues();values.put(COLUMN_NAME, name);values.put(COLUMN_AGE, age);return db.insert(TABLE_NAME, null, values); }
2--删除数据
public int deleteUserById(long id) {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();return db.delete(TABLE_NAME, COLUMN_ID + "=?", new String[]{String.valueOf(id)}); }
3--修改数据
public int updateUser(long id, String newName, int newAge) {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();ContentValues values = new ContentValues();values.put(COLUMN_NAME, newName);values.put(COLUMN_AGE, newAge);return db.update(TABLE_NAME, values, COLUMN_ID + "=?", new String[]{String.valueOf(id)}); }
4--查询数据
public Cursor getAllUsers() {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();return db.query(TABLE_NAME, null, null, null, null, null, null); }public Cursor getUserById(long id) {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();return db.query(TABLE_NAME, null, COLUMN_ID + "=?", new String[]{String.valueOf(id)}, null, null, null); }
3)SQLite数据库中的事务
事务是一系列数据库操作,它们被视为单个工作单元,要么全部执行成功,要么都不执行。这有助于确保数据的一致性和完整性。
public boolean performTransaction() {SQLiteDatabase db = new DatabaseHelper().getWritableDatabase();try {db.beginTransaction(); // 开始事务// 执行一系列数据库操作ContentValues values = new ContentValues();values.put(COLUMN_NAME, "John");values.put(COLUMN_AGE, 30);db.insert(TABLE_NAME, null, values);values.clear();values.put(COLUMN_NAME, "Jane");values.put(COLUMN_AGE, 25);db.insert(TABLE_NAME, null, values);db.setTransactionSuccessful(); // 标记事务为成功return true;} finally {db.endTransaction(); // 结束事务} }
如果在事务过程中发生错误,setTransactionSuccessful()
不会被调用,因此事务将会回滚,所有在该事务内的更改都将被撤销。这样可以防止数据不一致的情况发生。
相关文章:
Android中的三种数据存储方式
目录 1.文件存储 1)内部存储 1--MODE_PRIVATE: 2--MODE_APPEND: 3--MODE_WORLD_READABLE: 4--MODE_WORLD_WRITEABLE: 5--简单使用 3)外部存储 4)内部读取 4)外部读取 2.SharePreferences存储 1)基本概念 2)…...
VS2022中Qt环境配置步骤
VS2022中Qt环境配置步骤 一、安装QT 下载QT:从QT官网上下载QT,在安装过程中,可以根据自己的需求选择适合的QT版本。若不确定,建议选择最新版本,这有助于提高开发效率。 二、安装Visual Studio 2022 选择组件&#…...
【前端】 常用的版本控制符号汇总
前端的版本控制符主要用于管理前端项目中依赖包的版本。它们通常在package.json文件中定义,帮助开发者指定所需的库和框架的版本范围。以下是一些关键概念: 版本控制符号详解: 1. 依赖管理 在前端开发中,依赖管理工具ÿ…...
OWASP Top 10 漏洞详解:基础知识、面试常问问题与实际应用
OWASP(开放式Web应用程序安全项目)是一个全球性非营利组织,致力于提高软件安全性。OWASP Top 10 是其发布的十大Web应用程序安全风险列表,广泛应用于安全领域的学习和实践。本文将详细介绍OWASP Top 10 漏洞的基础知识、面试常见问…...

实景三维赋能自然资源精细化管理创新
在自然资源管理领域,如何实现精细化、高效化管理一直是我们面临的挑战。随着实景三维技术的兴起,这一挑战迎来了新的解决方案。今天,我们将探讨实景三维技术如何赋能自然资源的精细化管理。 1. 实景三维技术概述 实景三维技术是一种集成了遥…...

Science Robotics 通过新材料打造FiBa软机器人 可实现四种形态进化
近几年由于材料科学的进步,软机器人相关技术近几年研究成果显著,与传统的刚性机器人相比,软机器人的设计灵感来源于自然界中的生物系统,如蠕虫、章鱼、壁虎和青蛙等。这些生物利用柔软、有弹性的材料,在复杂环境中展现…...

C++ 的特性可以不用在主函数中调用
写完代码,都找不到从哪里进去...

香港大学神作 LightRAG 横空出世!AI 检索生成系统革命,秒懂复杂信息,动态数据无所遁形!
❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦! 微信订阅号|搜一搜&…...

云栖实录 | 智能运维年度重磅发布及大模型实践解读
本文根据2024云栖大会实录整理而成,演讲信息如下: 演讲人: 钟炯恩 | 阿里云智能集团运维专家 张颖莹 | 阿里云智能集团算法专家 活动: 2024 云栖大会 AI 可观测专场 -智能运维:云原生大规模集群GitOps实践 2024 …...
Vue3中防止按钮重复点击的方式
本文列两种方式,推荐第一种,经过长时间测试第二种防止的还是会漏,这里也列一下 ①使用定时器(推荐) 判断3秒钟之内方法只能执行一次 <el-button click"handleClick" type"primary" :loading…...

windows主机重新安装zabbix agent提示please clear the previous agent registration
目录 1. Zabbix Agent1.1 错误提示 2. 解决方法2.1 管理员运行cmd2.2 可以正常安装 1. Zabbix Agent 1.1 错误提示 2. 解决方法 2.1 管理员运行cmd 输入 sc.exe delete “Zabbix Agent” 或者 sc.exe delete “Zabbix Agent 2” 如果成功会出现“[SC] DeleteService SUCCES…...

一个将.Geojson文件转成shapefile和kml文件的在线页面工具
最近需要读取.geojson格式的流域边界文件。在谷歌地球桌面版和globalMapper中均无法正常读取。下面我发现的一个在线的平台可以很好实现这一功能。 GeoJSON to SHP Converter Online - MyGeodata Cloud ❤️欢迎点赞收藏❤️...

Mamba学习笔记(1)——原理基础
文章目录 Mamba: Linear-Time Sequence Modeling with Selective State Spaces0 Abstract1 Introduction2 State Space Models3 Selective State Space Models3.1 Motivation: Selection as a Means of Compression3.2 Improving SSMs with Selection3.3 Efficient Implementat…...
linux应用
检查Python程序未运行则重新运行 entity_program定时杀掉进程重新运行 match_program定时检查是否运行,未运行则启动 (注意echo时间时,date和中间要有空格) #!/bin/bash# 检测的Python程序名称 entity_program"entity.py" match_program"…...

【千库网-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

【LwIP源码学习3】TCP协议栈分析——数据接收流程
前言 本文介绍代码在lwip的tcp_in.c文件中,主要介绍TCP协议栈中数据的接收流程。 正文 1、一个正常的TCP数据,首先会传入到 tcp_input(struct pbuf *p, struct netif *inp)函数,其中指针p指向传入的数据流。 2、从数据流中获取TCP头部 …...

【bug】finalshell向远程主机拖动windows快捷方式导致卡死
finalshell向远程主机拖动windows快捷方式导致卡死 问题描述 如题,作死把桌面的快捷方式拖到了finalshell连接的服务器面板中,导致finalshell没有响应(小概率事件,有时会触发) 解决 打开任务管理器查看finalshell进…...

基于SpringBoot剧本杀管理系统 【附源码】
基于SpringBoot剧本杀管理系统 效果如下: 系统首页界面 系统注册页面 剧本信息详细页面 后台登录界面 管理员主界面 剧本信息界面 剧本预约界面 作者主界面 研究背景 随着现代社会生活节奏的加快,人们越来越渴望通过各种娱乐活动来释放压力和增进社交…...
Linux 命令 —— grep、tail、head、cat、more、less(查看日志常用命令)
文章目录 查看日志常用命令grep 命令tail 命令head 命令cat 命令more 命令less 命令 查看日志常用命令 grep tail、head、cat、more、less grep 命令 grep [options] PATTERN filename:查找日志文件中的 PATTERN 关键字,用于过滤/搜索的特定字符。PAT…...
知识见闻 - 美国连线杂志
https://www.wired.com/ WIRED 杂志是一份月刊,重点关注新兴技术如何影响文化、经济和政治。在快速变革的世界中,它已成为信息和思想的重要来源。 WIRED magazine is a monthly publication that focuses on how emerging technologies impact culture, …...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...