4类Storage方案(AS开发实战第四章学习笔记)
4.1 共享参数SharedPreferences
SharedPreferences按照key-value对的方式把数据保存在配置文件中,该配置文件符合XML规范,文件路径是/data/data/应用包名/shared_prefs/文件名.xml,下面是一个共享参数的XML文件示例:
<?xml verson=’1.0’ encoding=’utf-8’ standalone=’yes’?>
<map>
<string name=”name”>Mr Lee</string>
<int name=”age” value=”30” />
<boolean name=”married” value=”true” />
<float name=”weight” value=”100.0” />
</map>
示例代码:
private SharedPreferences sps;
sps = getSharedPreferences(“share”, Context.MODE_PRIVATE);
getSharedPreferences的第一个参数是文件名,上面的share表示当前使用的共享文件名是share.xml,第二个参数是操作模式,一般都填MODE_PRIVATE表示私有模式
SharedPreferences.Editor editor = sps.edit();
editor.putString(“name”, “Mr Lee”);
editor.putInt(“age”, “30”);
editor.putBoolean(“married”, “true”);
editor.putFloat(“weight”, “100f”);
editor.commit();
String name = sps.getString(“name”, “”);
int age = sps.getInt(“age”, 0);
boolean married = sps.getBoolean(“married”, false);
float weight = sps.getFloat(“weight”, 0);
共享参数的get方法第二个参数表示默认值
(这里例程用了map,有待研究)
4.2 数据库SQLite
SQLite的基本用法:
(1)建表时为避免重复操作,应加上IF NOT EXISTS关键词,例如CREATE TABLE IF NOT EXISTS table_name
(2)删表时为避免重复操作,应加上IF EXISTS关键词,例如DROP TABLE IF EXISTS table_name
(3)添加新列时使用ALTER TABLE table_name ADD COLUMN …
(4)在SQLite中,ALTER语句每次只能添加一列,如果要添加多列,就只能分多次添加
(5)SQLite支持整型INTEGER,字符串VARCHAR,浮点数FLOAT,但不支持布尔类型,布尔类型数要使用整型保存,如果直接保存布尔数据,在入库时SQLite就会自动将其转为0或1
(6)SQLite建表时需要一个唯一标识字段,字段名为_id,每建一张新表都要例行公事加上该字段定义,具体属性定义为_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
(7)条件语句等号后面的字符串值要用单引号括起来,如果没有使用单引号括起来,在运行时就会报错
SQLiteDatabase是SQLite的数据库管理类,我们可以在活动页面代码或任何能取到Context的地方获取数据库示例,参考代码如下:
//创建数据库,如果已存在就打开
SQLiteDatabase db = getApplicationContext().openOrCreateDatabase(“test.db”, Context.MODE_PRIVATE, null);
//删除数据库
getApplicationContext().deleteDatabase(“test.db”);
SQLiteDatabase提供了若干操作数据表的API,常用的方法有3类,列举如下:
1.管理类,用于数据库层面的操作
openDatabase:打开指定路径的数据库
isOpen:判断数据库是否已打开
close:关闭数据库
getVersion:获取数据库的版本号
setVersion:设置数据库的版本号
2.事务类,用于事务层面的操作
beginTransaction:开始事务
setTransactionSuccessful:设置事务的成功标志
endTransaction:结束事务,执行本方法时,系统会判断是否已执行setTransactionSuccessful,如果之前已设置就提交,如果没有设置就回滚
3.数据处理类,用于数据表层面的操作
execSQL:执行拼接好的SQLite控制语句,一般用于建表、删表、变更表结构
delete:删除符合条件的记录
update:更新符合条件的记录
insert:插入一条记录
query:执行查询操作,返回结果集的游标
rawQuery:执行拼接好的SQL查询语句,返回结果集的游标
SQLiteOpenHelper
具体使用步骤如下:
(1)新建一个继承自SQLiteOpenHelper的数据库操作类,提示重写onCreate和 OnUpgrade两个方法,其中onCreate方法只在第一次打开数据库时执行,在此可进行表结构创建的操作;onUpgrade方法在数据库版本升高时执行,因此我们可以在onUpgrade函数内部根据新旧版本号进行表结构变更处理
(2)封装保证数据库安全的必要方法,包括获取单例对象,打开数据库连接,关闭数据库连接
(3)提供对表记录进行增加、删除、修改、查询的操作方法
Cursor的常用方法:
1.游标控制类方法,用于指定游标的状态
Close:关闭游标
isClosed:判断游标是否关闭
isFirst:判断游标是否在开头
isLast:判断游标是否在末尾
2.游标移动类方法,把游标移动到指定位置
moveToFirst:移动游标到开头
moveToLast:移动游标到末尾
moveToNext:移动游标到下一条记录
moveToPrevious:移动游标到上一条记录
move:往后移动游标若干条记录
moveToPosition:移动游标到指定位置的记录
3.获取记录类方法,可获取记录的数量、类型以及取值
getCount:获取结果记录的数值
getInt:获取指定字段的整型值
getFloat:获取指定字段的浮点数值
getString:获取指定字段的字符串值
getType:获取指定字段的字段类型
关于SQLiteOpenHelper的简单“封装”,见Database类的封装.rar
优化记住密码功能:
(1)声明一个UserDBHelper对象,然后在活动页面的OnResume方法中打开数据库连接,在onPause方法中关闭数据库连接,示例代码如下:
@Override
protected void onResume() {
super.onResume();
mHelper
= UserDBHelper.getInstance(this, 2);
mHelper.openWriteLink();
}
@Override
protected void onPause() {
super.onPause();
mHelper.closeLink();
}
(2)在登录成功时,如果用户勾选了“记住密码”,就使用数据库保存手机号码与密码在内的登录信息,在loginSuccess函数中增加如下代码:
if(bRemember) {
UserInfo
info = new UserInfo();
info.phone =
et_phone.getText().toString();
info.update_time
= DateUtil.getNowDateTime(“yyyy-MM-dd HH:mm:ss”);
mHelper.insert(info);
}
(3)再次打开登录页面,用户输入手机号完毕后点击密码输入框时,App到数据库中根据手机号查找登录记录,并将记录结果中的密码填入密码框
EditText比较特殊,点击后只是让其获得焦点,再次点击才会触发点击事件。也就是说,要连续点击两次EditText才会处理点击事件,这里提供一个解决办法:先给密码框注册一个焦点变更监听器,比如下面这行代码:
et_password.setOnFocusChangeListener(this);
这个焦点变更监听器要实现接口OnFocusChangeListener,对应的事件处理方法是onFocusChange,将数据库查询操作放在该方法中,详细代码如下:
@Override
public void onFocusChange(View v, boolean
hasFocus) {
String
phone = et_phone.getText().toString();
if(v.getId()
== R.id.et_password) {
if(phone.length()
> 0 && hasFocus == true) {
UserInfo
info = mHelpler.queryByPhone(phone);
if(info
!= null) {
et_password.setText(info.password);
}
}
}
}
4.3 SD卡文件操作
获取手机上的SD卡信息通过Environment类实现,该类是App获取各种目录信息的工具,主要方法有以下7种:
getRootDirectory:获得系统根目录的路径
getDataDirectory:获得系统数据目录的路径
getDownloadCacheDirectory获得下载缓存目录的路径
getExternalStorageDirectory:获得外部存储(SD卡)的路径
getExternalStorageState:获得SD卡的状态
SD卡的存储状态取值说明
Environment类的存储状态常量名 |
常量值 |
常量说明 |
MEDIA_UNKNOWN |
unknown |
未知 |
MEDIA_REMOVED |
removed |
已经移除 |
MEDIA_UNMOUNTED |
unmounted |
未挂载 |
MEDIA_CHECKING |
checking |
正在检查 |
MEDIA_NOFS |
nofs |
不支持的文件系统 |
MEDIA_MOUNTED |
mounted |
已经挂载,且是可读写状态 |
MEDIA_MOUNTED_READ_ONLY |
mounted_ro |
已经挂载,且是只读状态 |
MEDIA_SHARED |
shared |
当前未挂载,但通过USB共享 |
MEDIA_BAD_REMOVAL |
bad_removal |
未挂载就被移除 |
MEDIA_UNMOUNTABLE |
unmountable |
无法挂载 |
MEDIA_EJECTING |
ejecting |
正在弹出 |
getStorageState:获得指定目录的状态
getExternalStoragePublicDirectory:获得SD卡指定类型目录的路径
SD卡的目录类型取值说明
Environment类的目录类型 |
常量值 |
常量说明 |
DIRECTORY_DCIM |
DCIM |
相片存放目录(包括相机拍摄的图片和视频) |
DIRECTORY_DOCUMENTS |
Documents |
文档存放目录 |
DIRECTORY_DOWNLOADS |
Download |
下载文件存放目录 |
DIRECTORY_MOVIES |
Movies |
视频存放目录 |
DIRECTORY_MUSIC |
Music |
音乐存放目录 |
DIRECTORY_PICTURES |
Pictures |
图片存放目录 |
为正常操作SD卡,需要在AndroidManifest.xml中声明SD卡的权限,具体代码如下:
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android:permission.MOUNT_UNMOUNT_FILESYSTEMS”>
示例:
desc =
Environment.getRootDirectory().getAbsolutePath());
desc = Environment.getDataDirectory().getAbsolutePath());
desc = Environment.getDownloadCacheDirectory().getAbsolutePath());
desc = Environment.getExternalStorageDirectory().getAbsolutePath());
desc = Environment.getExternalStorageState());
desc = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM));
//DIRECTORY_DOCUMENTS是Android4.4.2(SDK19)及以上版本才有的常量
//如果不做SDK版本判断,那么在低版本Android(例如4.2.2)上运行会报错
//java.lang.NoSuchFieldError: android.os.Environment.DIRECTORY_DOCUMENTS
//因此在获取DIRECTORY_DOCUMENTS时要加上判断条件if (VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) ,
其他的则不用,示例如下:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
文本文件读写&图片文件读写:工具类FileUtil.java
文本文件的读写一般借助于FileOutputStream和FileInputStream
Android的图片处理类是Bitmap,App读写Bitmap可以使用FileOutputStream和FileInputStream,不过在实际开发中,读写图片文件一般用性能更好的BufferedOutputStream和BufferedInputStream,保存图片文件时用到的Bitmap的compress方法,可指定图片类型和压缩质量,打开图片文件时使用BitmapFactory的decodeStream方法。
事实上,BitmapFactory还提供了其他方法:
decodeFile:该方法直接传文件路径的字符串,即可将指定路径的图片读取到Bitmap对象
decodeResource:该方法可从资源文件中读取图片信息,第一个参数一般传getResources(),第二个参数传drawable图片的资源id,如R.drawable.phone
4.4 Application基础
在App运行过程中有且仅有一个Application对象贯穿整个生命周期,activity节点的上级正是application
Application的生命周期覆盖App运行的全过程,不像短暂的Activity生命周期,只要进入别的页面,原页面就被停止或销毁,因此,通过利用Application的持久存在性可以在Application对象中保存全局变量,适合在Application中保存的全局变量主要有下面3类数据:
(1)会频繁读取的信息,如用户名,手机号等
(2)从网络上获取的临时数据,为节约流量、减少用户等待时间,想暂时放在内存中供下次使用,如logo、商品图片等
(3)容易因频繁分配内存而导致内存泄漏的对象,如Handler对象
要想通过Application实现全局内存的读写,得完成以下3项工作:
(1)写一个继承自Application的类MainApplication,该类要采用单例模式,内部声明自身类的一个静态成员对象,在创建app时把自身赋值给这个静态对象,然后提供该静态对象的获取方法getInstance
(2)在Activity中调用MainApplication的getInstance方法,获得MainApplication的一个静态对象,通过该对象访问MainApplication的公共变量和公共方法
(3)不要忘了在AndroidManifest.xml中注册新定义的Application类名,即在application节点中增加android:name属性,值为.MainApplication
样例类:MainApplication.java
(MainApplication类可以重写的方法主要有以下4个:
onCreate:在App启动时调用
onTerminate:在App退出时调用(该方法就是个摆设……)
onLowMemory:在低内存时调用
onConfigurationChanged:在配置改变时调用,例如从竖屏变为横屏)
完成自定义MainApplication类的代码后,Activity页面代码即可直接通过MainApplication.getInstance().mInfoMap对全局变量进行增删改查操作
4类Storage方案(AS开发实战第四章学习笔记)的更多相关文章
- 菜单Menu(AS开发实战第四章学习笔记)
4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...
- Spring实战第四章学习笔记————面向切面的Spring
Spring实战第四章学习笔记----面向切面的Spring 什么是面向切面的编程 我们把影响应用多处的功能描述为横切关注点.比如安全就是一个横切关注点,应用中许多方法都会涉及安全规则.而切面可以帮我 ...
- 《Node.js开发实战详解》学习笔记
<Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...
- 《Cocos2d-x游戏开发实战精解》学习笔记4--实战一个简单的钢琴
上一节学习了使用Cocos2d-x播放音乐的方法,但是那种方法一般只适合于播放较大的音乐,而一般比较短小的音乐(如游戏中的打斗.按键音效等)则要通过playEffect来播放.本节使用该方法以及之前学 ...
- 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音
<Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...
- Spring实战第六章学习笔记————渲染Web视图
Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...
- Spring实战第五章学习笔记————构建Spring Web应用程序
Spring实战第五章学习笔记----构建Spring Web应用程序 Spring MVC基于模型-视图-控制器(Model-View-Controller)模式实现,它能够构建像Spring框架那 ...
- 《Cocos2d-x游戏开发实战精解》学习笔记1--在Cocos2d中显示图像
Cocos2d-x中的图像是通过精灵类来显示的.在Cocos2d-x中游戏中的每一个角色.怪物.道具都可以理解成是一个精灵,游戏背景作为一种特殊的单位将其理解成是一个精灵也没有什么不妥.在源文件本章目 ...
- 《Cocos2d-x游戏开发实战精解》学习笔记2--在Cocos2d-x中显示一行文字
在Cocos2d-x中要显示文字就需要用到Label控件.在3.x版本的Cocos2d中,舍弃了之前版本所使用的LabelTTF.LabelAtlas.LabelBMFont 3个用于显示文字的类,而 ...
随机推荐
- 最新版IntelliJ IDEA2019.1破解教程(2019.04.08更新)
[原文链接]:https://www.tecchen.xyz/idea-crack.html 我的个人博客:https://www.tecchen.xyz,博文同步发布到博客园. 由于精力有限,对文章 ...
- 踩方格 OpenJ_Bailian - 4103
有一个方格矩阵,矩阵边界在无穷远处.我们做如下假设:a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上:b. 走过的格子立即塌陷无法再走第二次:c. 只能向北.东.西三个 ...
- 五一,期待一场这样的旅行,提前预祝Csdner五一快乐
五一,期待一场这样的旅行,提前预祝Csdner五一快乐 五一,你是否期待一次这样的旅行: 住在一间安静优美的小屋,在鸟鸣中起床,推窗有花香铺面而来.早餐过后,在阳光温暖的抚摸里,骑车踏青或光脚奔跑. ...
- (转)Python 运算符
原文:https://blog.csdn.net/liang19890820/article/details/69690954 简述 在 Python 中,运算符是执行算术或逻辑运算的特殊符号,操作的 ...
- 【Kafka】Producer配置
名称 描述 类型 默认值 bootstrap.servers kafka集群地址,ip+端口,以逗号隔开.不管这边配置的是什么服务器,客户端会使用所有的服务器.配置的列表只会影响初始发现所有主机.配置 ...
- redis的key
Redis支持的数据模型: Redis支持的数据类型: redis的key: Redis对key的操作: 执行命令cd /usr/local/redis进入到redis的启动目录,执行./redis ...
- Git fetch & pull 区别
1 简单概括 2 git fetch 的用法 3 git pull的用法 文章来源:https://blog.csdn.net/qq_36113598/article/details/78906882
- display:block、inline、inline-block的区别及应用案例
A.display:block就是将元素显示为块级元素. block元素的特点是: 1.总是在新行上开始: 2.高度,行高以及顶和底边距都可控制: 3.宽度缺省是它的容器的100%,除非设定一个宽度; ...
- Session 与 Cookie
Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态.它们本身只是HTTP中的一个配置项,在servlet规范中也只对应一个类而已. 理解 Cookie 通俗地说就是当一 ...
- 【总结】java 后台文件上传整理
public Map<String,String> clientUploadAttachment(Long belongId, String fileSource, MultipartFi ...