005 Android之数据存储
文章目录
- Android文件系统
- Android文件的访问权限
- 文件访问权限实例
- 数据存储方式
- 内部存储
- 内部存储实例
- 外部存储
- Shared Preferences
- Shared Preferences实例
- sqlite数据库
- sqlite概述
- Android中访问Sqlite数据库的类
- SQLiteOpenHelper类的使用
- SQLiteDatabase的使用
Android文件系统
在Android中,每一个应用都是一个独立的用户。文件或者文件夹的权限使用10个字母来表示
第一个字母:
- d表示文件夹
- -表示文件
第一组rwx,表示的是文件拥有者(owner)对文件的权限
- r:read
- w:write
- x:execute
第二组rwx,表示的是文件拥有者属于同一用户组的用户对文件的权限
第三组rwx,表示的是其他用户对文件的权限
rwx分别代表数值421
Android文件的访问权限
Android中的文件是有很多权限的,我们自己创建的文件也是会有权限的,权限相关API
FileInputStream openFileOutput(String name); //读取文件
FileOutputStream openFileOutput(String name,int mode); //模式
这个API访问的目录是data/data包名/files
,打开应用程序的数据文件夹下的name文件对应输出流有下面几种
模式 | 说明 |
---|---|
Context.MODE_PRIVATE | 私有模式,第二次读写会覆盖文件 |
Context.MODE_APPEND | 追加方式,判断文件存在,追加到文件末尾 |
Context.MODE_WORLD_READABLE | 其他程序可以读(不推荐使用) |
Context.MODE_WORLD_WRITEABLE | 其他程序可以写(不推荐使用 |
文件访问权限实例
界面代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_private"android:onClick="onClick"android:text="私有方式"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_append"android:onClick="onClick"android:text="追加"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_read"android:onClick="onClick"android:text="全局可读"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_write"android:onClick="onClick"android:text="全局可写"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_global_rw"android:onClick="onClick"android:text="全局可读可写"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_private"android:onClick="onClick"android:text="私有方式"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>
设置五个按钮,分别对应不同的文件权限,然后编写响应事件
public void onClick(View view) {int id=view.getId();String name=null;int mode=0;switch (id){case R.id.btn_private:name="private.txt";mode=Context.MODE_PRIVATE;break;case R.id.btn_append:name="append.txt";mode=Context.MODE_APPEND;break;case R.id.btn_global_read:name="global_read.txt";mode=Context.MODE_WORLD_READABLE;break;case R.id.btn_global_write:name="global_write.txt";mode=Context.MODE_WORLD_WRITEABLE;break;case R.id.btn_global_rw:name="global_rw.txt";mode=Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE;break;}try {FileOutputStream outputStream=openFileOutput(name,mode);String content="这里是内容";outputStream.write(content.getBytes());outputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
当点击按钮以后
在files目录下会生成不同的文件
数据存储方式
在Android SDK中关于数据存储一共有以下几种:
- 内部存储:存储在手机内存中,适合保存一些不太大的临时数据
- 外部存储(存储在SD卡中):基本上什么数据都可以保存
- Sqlite数据库:适合保存有一定规则的数据
- Shared Preferences:存储在APP安装目录下,会生成一个xml文件,只能本程序访问,适合存储简单零散的数据
- 网络存储:从服务器中获取数据
- Content Provider(内容提供者):应用与应用数据共享的通道
内部存储
内部存储只能存储在自身app的数据区
目录:data/data/包名/xxx.txt
写入和读取需要以下几个类:
- 文件信息类:File类
- 保存文件使用:FileOutputStream类
- 读取文件使用:FileInputStream类
- 字节流转换成字符流:BufferedReader类
内部存储实例
实例:用户登陆程序
功能:登陆之后勾选记住用户名,下次登陆可以直接填充
分析思路:
- 设计布局
- 处理按钮事件,完成保存代码操作
- 初始化界面时,读取文件加载用户名
布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><EditTextandroid:id="@+id/edit_user"android:hint="请在此输入用户名"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/edit_pass"android:hint="请在此输入密码"android:layout_width="match_parent"android:layout_height="wrap_content" /><CheckBoxandroid:id="@+id/checkbox"android:text="记住用户名"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btnclick"android:onClick="btnClick"android:text="登陆"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</LinearLayout>
接着编写按钮响应事件,用于保存用户名和密码
public void btnClick(View view) {//获取用户名EditText editText=findViewById(R.id.edit_user);String user=editText.getText().toString();//获取密码EditText editText2=findViewById(R.id.edit_pass);String pass=editText.getText().toString();//模拟判断登陆情况if (!user.equals(pass)){return;}Toast.makeText(this,"成功登陆",Toast.LENGTH_LONG).show();//获取界面对象CheckBox checkBox=findViewById(R.id.checkbox);//判断是否被选中if (checkBox.isChecked()){//保存用户名String path="/data/data/com.example.a87321.login/config.txt";File file=new File(path);try {FileOutputStream outputStream=new FileOutputStream(file);byte bytes[]=user.getBytes();outputStream.write(bytes);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
运行程序
在/data/data/包名/
这个路径下,可以看到保存的config文件;接着编写代码,在主函数入口读取配置文件的帐号密码
private void InitData() {//获取控件对象EditText editText=findViewById(R.id.edit_user);//读取配置文件的用户名,设置对象String packageName=getPackageName();String path="/data/data/"+packageName+"/config.txt";File file=new File(path);try {FileInputStream inputStream=new FileInputStream(file);byte bytes[]=new byte[(int)file.length()];inputStream.read(bytes);String s=new String(bytes);editText.setText(s);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
接着在界面加载时,就会自动读取用户名,显示到界面,效果如图:
外部存储
外部存储就是存储在SD卡中
SD卡的路径
- sdcard:2.3之前的SD卡路径
- mnt/sdcard:4.3之前的SD卡路径
- storage/sdcard:4.3之后的SD卡路径
使用方式和内部存储差不多,只是写入的路径不同,这里不再举例
Shared Preferences
Shared Preferences是使用的最多的数据存储方式,这种数据存储方式保存的信息只能是基本数据类型和字符串,适用于保存解锁密码用户名以及一些配置信息。
核心原理:读取写入操作的是app安装目录下的/data/data/<package name>/shared_prefs
目录下,保存的文件是xml格式
使用Shared Preferences写入数据
Shared Preferences是一个接口,只提供读取数据的功能;Shared Preferences的内部接口Editor类的edit()方法,提供写入功能。使用步骤如下:
- 获取输入值
- 创建一个Shared Preferences.Editor接口对象
- 将获取过来的值放入文件
- 提交
- 其他处理,提示信息等
Shared Preferences实例
界面代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:id="@+id/edit1"android:hint="请在此输入密码"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_set"android:text="保存口令"android:textSize="20sp"android:onClick="btnClick"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn_get"android:text="获取口令"android:textSize="20sp"android:onClick="btnClick"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>
接着编写响应事件保存pass
private void setPass() {//获取口令EditText editText=findViewById(R.id.edit1);String pass=editText.getText().toString();//获取SharedPreferences对象SharedPreferences sp=getSharedPreferences("lock",Context.MODE_PRIVATE);//获取Editor对象SharedPreferences.Editor editor=sp.edit();//压入数据editor.putString("pass",pass);//提交保存editor.commit();//提示信息Toast.makeText(this,"保存完成",Toast.LENGTH_LONG).show();
实际效果如图:
点击保存口令以后
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cvKULbO-1623032601181)(005 Android之数据存储.assets/1622904828683.png)]
会生成shared_prefs文件夹,并产生一个xml文件,里面存储的是保存的pass数据。接着来完成pass的读取操作
private void getPass() {//获取SharedPreferences对象SharedPreferences sp=getSharedPreferences("lock",Context.MODE_PRIVATE);//获取数据String pass=sp.getString("pass","none");if (pass.equals("none")==false){//提示信息Toast.makeText(this,"口令:"+pass,Toast.LENGTH_LONG).show();}}
读取操作相对要比写入简单的多,直接调用getString方法就能获取数据,效果如图:
sqlite数据库
sqlite概述
Sqlite是一款非常优秀且广泛使用于嵌入式软件中的数据库,它的主要特点,一是小巧,二是免费开源。基于这两点,Google的android系统内置了Sqlite,适用于一些有规则的数据,比如电话信息;与所有数据库一样,具有增删改查的功能
Android中访问Sqlite数据库的类
Android中有两个类用于访问sqlite数据库
SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本的更新。一般是建立一个类继承它,并实现onCreate和onUpgrade方法
方法名 | 说明 |
---|---|
SQLiteOpenHelper | 构造方法 |
onCreate | 第一次创建数据库时调用 |
onUpgrade | 版本更新时调用 |
getWritableDatabase | 创建数据库,并以读写方式打开数据库,磁盘满了不能写时会出错 |
getReadableDatabase | 创建数据库,先以读写方式打开数据库,磁盘满了再以只读方式打开 |
SQLiteDatabase是一个数据库访问类,这个类封装了一系列数据库操作的API,可以对数据库进行增删改查
方法名 | 说明 |
---|---|
delete | 删除数据行 |
insert | 添加数据行 |
update | 更新数据行 |
execSQL | 执行一个sql语句 |
close | 关闭数据库 |
query | 查询指定的数据表返回一个带游标的数据集 |
rawQuery | 运行一个预置的SQL语句,返回一个带游标的数据集 |
SQLiteOpenHelper类的使用
首先编写界面代码,设置6个按钮,分别对应不同的数据库功能
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn1"android:onClick="btnCreate"android:text="创建数据库"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn2"android:onClick="btnUpdate"android:text="更新数据库"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn3"android:onClick="btnInsert"android:text="插入数据"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn4"android:onClick="btnUpdateData"android:text="更新数据"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn5"android:onClick="btnSelectData"android:text="查询数据"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /><Buttonandroid:id="@+id/btn6"android:onClick="btnDelData"android:text="删除数据"android:textSize="20sp"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIVwT87i-1623032601186)(005 Android之数据存储.assets/1622955011480.png)]
接着新建一个类,并继承SQLiteOpenHelper
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bS4rce2R-1623032601191)(005 Android之数据存储.assets/1622955077781.png)]
然后重写onCreate和onUpgrade方法
然后实现构造方法
重写onCreate方法,创建一个数据库
@Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {//输出日志Log.i("DBHelper","Create a database");//创建数据库的sql语句String sql="create table user(id int,name varchar(20))";//执行创建数据库操作sqLiteDatabase.execSQL(sql);}
重写upgrade方法
@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {//输出日志Log.i("DBHelper","update a database");}
接着编写创建数据库按钮的响应事件
public void btnCreate(View view) {//创建一个DatabaseHelper对象DBHelper dbHelper=new DBHelper(MainActivity.this,"test.db",null,1);//取得一个只读的数据库对象SQLiteDatabase db1=dbHelper.getReadableDatabase();db1.close();}
点击创建数据库
即可在database目录下生成数据库文件
编写更新数据库响应事件
public void btnUpdate(View view) {DBHelper dbHelper2=new DBHelper(MainActivity.this,"test.db",null,2);//更新版本SQLiteDatabase db2=dbHelper2.getReadableDatabase();db2.close();}
在点击更新数据之后,会自动调用onUpgrade方法打印日志
SQLiteDatabase的使用
插入数据
public void btnInsert(View view) {//获取存放数据的ContentValues对象ContentValues values=new ContentValues();//向ContentValues中存放数据values.put("id",1);values.put("name","zhangsan");//获取数据库对象DBHelper dbhelper3=new DBHelper(this,"test.db",null,2);SQLiteDatabase db3=dbhelper3.getWritableDatabase();//数据库执行插入命令db3.insert("user",null,values);db3.close();}
更新数据
public void btnUpdateData(View view) {//准备要更新的数据对象ContentValues values2=new ContentValues();values2.put("name","lisi");//获取数据库对象DBHelper dbhelper4=new DBHelper(this,"test.db",null,2);SQLiteDatabase db4=dbhelper4.getWritableDatabase();//执行sql语句db4.update("user",values2,"id=?",new String[]{"1"});db4.close();}
查询数据
public void btnSelectData(View view) {//获取数据库对象DBHelper dbhelper5=new DBHelper(this,"test.db",null,2);SQLiteDatabase db5=dbhelper5.getWritableDatabase();//创建游标对象Cursor cursor=db5.query("user",new String[]{"id","name"},"id=?",new String[]{"1"},null,null,null,null);//利用游标遍历所有数据对象while (cursor.moveToNext()){String name=cursor.getString(cursor.getColumnIndex("name"));Log.i("MainActivity","query-->"+name);}db5.close();}
删除数据
public void btnDelData(View view) {//获取数据库对象DBHelper dbhelper6=new DBHelper(this,"test.db",null,2);SQLiteDatabase db6=dbhelper6.getWritableDatabase();//删除数据db6.delete("user","id=?",new String[]{"1"});db6.close();}
005 Android之数据存储相关推荐
- android SharedPreferences数据存储
android SharedPreferences数据存储 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存 ...
- android 储存方案,Android本地数据存储方案(一)
Android系列的博客主要是记录和总结自己在平时学习之中遇到的问题,方便日后用到时查看,同时也希望对读者有所帮助.不足之处,欢迎指正~ 在说到Android数据存储之前,先提一下数据持久化,所谓数据 ...
- Android的数据存储之一------SharedPreferences
下面将介绍下Android的数据存储,Android提供了5种方式存储数据: 1.SharedPreferences存储数据; 2.文件存储数据: 3.SQLite数据库存储数据: 4.使用Conte ...
- android常用的存储方式,Android 常见数据存储方式
Android 常见数据存储方式有以下三种:1.使用SharedPreferences存储数据:其本质就是一个xml文件,可以保存字符串.布尔值.基础数据.集合等数据.常用于存储较简单的参数设置. 2 ...
- Android之数据存储-刘志远-专题视频课程
Android之数据存储-17742人已学习 课程介绍 本课程介绍了Android中几种数据存储方式,让大家对Android中的数据存储一个系统的认识 课程收益 本课程介绍了A ...
- android app数据存储,基于Android开发的APP数据存储研究
谢原武+龙文 摘要: 作为一个完整的应用程序,数据存储操作是必不可少的.Android系统一共提供了四种数据存储方式分别为File文件存储.Shared Preferences存储.ContentPr ...
- Android常用数据存储之SharedPreferences存储和读取用法分享
一:Android常用数据存储,一共有五种方式,分别是 1.SharedPreferences储存数据, 2.文件存储 3.SQLite数据存储 4.ContentProvider储存数据 5.网络存 ...
- Android的数据存储和IO - 自动朗读(TTS)
Android的数据存储和IO - 自动朗读(TTS) 自动朗读又是Android提供的另一种另类的IO,蛮不错的哦,支持对指定文本内容进朗读,学习完这个内容我立马就让它朗读:wwj is a goo ...
- 【Android】数据存储,文件,数据库
Android中数据存储 一.在内部存储读写文件 1.文件io读写 写文件 //写入数据 private fun saveFile() {//将文件写入内部存储空间时,只能在本应用的目录中写入,不能写 ...
最新文章
- Python--day5--常用模块
- mysql Sql slow log_MySQL慢查询日志(SLOW LOG)
- python书籍_python书籍购买建议
- Win7 64位下PowerDesigner连接64位Oracle11g数据库
- [vue] vue生命周期总共有几个阶段?
- html设置referer防盗链,referer与防盗链
- 19春北理工计算机应用基础,19春北理工《计算机应用基础》在线作业(02)【标准答案】.doc...
- php类型运算符,PHP-运算符类型
- ESP8266开发之旅 阿里云物联网平台篇⑥ LED智能灯控制系统 全面讲解,上手一个小项目(MQTT客户端直连 + Web配网 + WebSocket局域网通信)
- 金山词霸2009sp3 (解决字典消失、屏幕不能取词问题)
- 对偶(duality)的含义
- ArcGis将2000国家大地坐标系转WGS84
- Nginx 正向代理互联网访问
- 人工智能的知识图,人工智能学习路线
- ruby-to_ary
- 诺基亚出了款香蕉手机!你是想对抗苹果嘛?
- 设计模式-05.01-行为型-观察者模板模式
- appium java 虫师_appium新手入门(9)—— appium API 之应用操作
- 在?快来pick你最喜爱的团队!
- 【转】谈NAND Flash的底层结构和解析
热门文章
- Paper之Algorithms:国内外Algorithms高质量论文、CUMCM分类推荐(建议收藏,持续更新)
- IDE之Visual Studio Code:Visual Studio Code的简介、安装、使用方法之详细攻略
- Centos环境下部署游戏服务器-软件安装
- js实现随机生成小方块
- Django 【补充】ORM多对多正向查询
- USACO Broken Necklace 题解(环展开成链,枚举)
- JAVA 解析xml字符串
- C++虚函数表,虚表指针,内存分布
- matplotlib.pyplot常用画图方式函数封装(一)——.plot绘制折线图及设置坐标轴箭头完美解决
- 第六章-template模板