安卓基础2:数据存储
安卓基础2:数据存储
测试的相关概念:
1、 按是否知道元源代码
a) 白盒:知道源码
b) 黑盒:不知道源码
2、 按测试的粒度
a) 方法测试 function test
b) 单元测试juint test
c) 集成测试 interaction test:数据的联调
d) 系统测试
3、 按测试强度
a) 冒烟测试
b) 压力测试:monkey测试随机点击
Android下的monkey测试指令:monkey –p报名 点击次数
单元测试:
步骤:
1、 创建一个类集成androidTestCase,该类就具备了单元测试的功能
2、 在AndroidManifest文件的application节点下配置一个uses-library
3、 在AndroidManifest文件中的mainifest节点下配置一个intrucmentation
4、如果忘记了怎么配置AndroidManifest文件中的intruction,可以创建一个Android Test Project
Logcat日志工具的使用
v: 所有log
d: debug级别
i: info级别
w: warming级别
e: error级别
注意:通常用logcat+断点调试可以找出所有信息。
开发时一般会将Log封装成一个Utile类,用一个开关控制logcat的打开关闭;
代码:
登陆案例:
程序过程
1、 写界面
2、 写业务逻辑层
a) 获取各个控件
b) 为按钮设置点击事件
c) 获取用户输入内容,并判断是否为空
d) 保存用户密码
e) 会先用户密码
代码
界面代码
业务逻辑层:
工具包:
将用户信息存储到私有目录下
将用户信息从私有内存中读出:
注:在android中有个TestUtils.isEmpty()来判断是否为空的方法;
私有目录:/data/data/,当应用程序安装上时会产生一个应用包名的目录,当应用程序卸载时会被删除。
Context.getFileDir().getPath;
SDcard目录:存放大文件数据时,当应用程序卸载时数据不会丢失
Environment.getExternalStorage
存储到sd卡,获取sd的大小及可用控件(重点)
Sdcard使用注意事项:
1、 需要添加sdcard权限
2、 判断SDcard剩余空间
3、 不适用硬性编码
File sdcard_dir = Enviroment.getExternalStorageDirectory();
代码
业务逻辑层:
工具类:
文件权限:
在linux下,文件的权限由10位表示:
如果用0-1码表示的话,“-”=0;其他都是1
Eg:”r-x”:101
文件保存的三种方式
SharedPreference
可以实现保存一些简单的标记信息。
获取数据过程:
1、 通过上下文对象获取sharepreference对象
2、 通过sharepreference对象获取一个editor对象
3、 通过editor对象put一些数据
4、 提交editor
代码:
注意:
1、调用PreferenceManager.getDefaultSharedPreference(context)存储以包名命名的唯一文件:
提交数据过程:
1、 通过上下文对象获取sharedpreference对象
2、 通过sharepreference的get方法获取存放的内容,并设置默认值
代码
生成xml的两种方式:
StringBuilder对字符进行拼接
代码:
使用android下提供的xmlSerilizer类进行序列化
a) 通过Xml类创建一个xml序列化对象
b) 为xml序列化对象设置初始化的参数,流,编码
c) 使用xml序列化对象序列化xml的文档声明信息
d) 使用xml序列化对象序列化xml的根节点
e) 通过循环遍历数据集合,将smss数据以标签的形式写入序列化对象
f) 设置xml序列化对象的根节点结束标签
g) 结束sml文档的写入
代码
使用pull解析xml
解析方式:
1、 dom:全文加载
2、 sax:基于事件驱动的逐行解析
3、 Pull:与sax类似,知识可以停顿
Pull解析方式:
1、 通过xml类获取一个xmlpullparser对象
2、 设置xmlpullparser对象的文件流读取流和编码
3、 后去解析器当前的事件类型
4、 循环遍历事件类型是否是文档结束符
5、 在循环中判断事件类型做相应的解析操作
代码:
短信备份和恢复
描述:
我们获取存储的短信进行短信备份:
代码:
短信格式:
存储的短信
事物处理层
备份短信工具类:
Context对象深入理解:
1、它描述的是一个应用程序环境的信息,即上下文。
2、该类是一个抽象(abstractclass)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
3、通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息 等。
于是,我们可以利用该Context对象去构建应用级别操作(application-level operations) 。
Context继承关系:
创建context:
熟悉了Context的继承关系后,我们接下来分析应用程序在什么情况需要创建Context对象的?应用程序创建Context实例的
情况有如下几种情况:
1、创建Application对象时, 而且整个App共一个Application对象
2、创建Service对象时
3、创建Activity对象时
Context描述了应用程序环境的信息,通过context可以获取资源和调用一些操作比如toast、发送intent等等,类似Win32中的句柄。但与句柄不同的是,在Win32中每个资源都有句柄(例如对话框),但在android中context只有activity、application和service。可以理解为拥有一个context就可以访问这个实例对应的资源,以及有权用这个实例调用方法。
生命周期:
public class MyActivity extends Activity{
public void method() {
mContext = this; // since Activity extendsContext
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
this 是Activity的实例,扩展了Context,其生命周期是Activity创建到销毁。getApplicationContext()返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁。Activity.this的context返回当前activity的上下文,属于activity,activity摧毁他就摧毁
getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文,SDK文档很少,不推荐使用
搞清楚了生命周期就会在使用过程中犯错误,比如有一个全局的数据操作类用到了context,这个时候就要getApplicationContext而不是用ACtivity,这就保证了数据库的操作与activity无关(不会一直引用Activity的资源,防止内存泄漏)
activity对象深入理解:
public class XxxActivity extends Activity
{
private EditText text;
public void onCreate(...)
{
....
text = this.findViewById(...);
...
下面就是一个触发按钮的事件(比如保存)
}
}
1、 activity代表一个界面,就是一个手机屏幕。activity对象在第一次调用的时候通过onCreate()创建,然后放到activity栈中,activity在栈中有集中状态,比如活跃了,暂停了等等。当kill或者调用onDestroy()的时候activity对象被销毁,从activity栈中移除。
2、 activity的onCreate()在第一次调用的时候执行,只执行这一次,之后不再执行,如果需要展示该activity,直接从activity栈中取得。 onCreate只是初始化操作,它只负责把单击事件的操作绑定到对应的按钮上,不负责执行里面的事件触发函数。
3、 onCreate()执行一次,匿名内部类里的回调函数执行的次数和触发事件的次数一样。
以单击事件为例,当执行onCreate()的时候,只是为按钮设置好一个“事件监听的接口”,我们这个接口的匿名内部类里回调函数的实现是不会被执行的,只有当按钮被单击的时候才会执行匿名内部类里的单击回调函数。比如我说,唉,这个皮球给你(执行onCreate()),我只是给你啦,皮球自己是不会弹起来的(匿名内部类里实现的回调函数不会执行),它只有在你拍它的时候(单击的时候)才会弹起来,你拍几次它就会谈起几次(回调函数执行的次数)!
Application对象深入理解:
Application同Activity和Service一样都是Android框架的组成部分。这个Application通常在app启动的时候就会自动创建。Application在app中是一个单例模式,而且Application也是整个app生命周期最长的对象。所有的Activity和Service都是共用着一个Application,所以Application通常用来共享数据,数据传递和数据缓存。
注意:
1.当两个Activity要传输大数据的时候,应尽量避免使用Intent传输,而是在Application里面建立HashMap,然后发送方Activity把数据放到Application的HashMap里面,然后把数据的索引通过Intent传输到接收方Activity。接收方Activity就可以从Application里面获取到发送方的传递的数据。
2.当从网络上下载的数据,可以将它暂时放到Application的HashMap里面,当app再次请求数据的时候如果发现Application里面已经有数据了,就不用再次从网上下载。
3.app的内存是有限制的,所以如果缓存的数据太多,应该要将缓存数据写入到本地的rom或者是sdcard上。、
4.Application是静态的,因此有一些对象和数据最后不要放到Application的引用。Application的生命周期很长,假如说,如果Application有某一个Activity的控件引用时,则当Activity想要finish的时候,内存会释放不了,造成内存泄漏。
Server对象深入理解:
Service也是运行在主线程中,只是没有界面.如果把Activity中不设置view,也可以实现类似的功能。跟正常理解的“服务”差不多,后台运行,可交互这样的一个东西。它跟Activity的级别差不多,但是他不能自己运行,需要通过某一个Activity或者其他Context对象来调用,Context.startService()和 Context.bindService()。
注意:
如果你在Service的onCreate或者onStart做一些很耗时间的事情,最好在Service里启动一个线程来完成,因为Service是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情。
Eg:比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务嘛,总是藏在后头的。
分析:
1、从设计的角度来讲:
Android的Activity的设计与Web页面非常类似,从页面的跳转通过连接,以及从页面的定位通过URL,从每个页面的独立封装等方面都可以看出来,它主要负责与用户进行交互。
Service则是在后台运行,默默地为用户提供功能,进行调度和统筹,如果一棵树的地上部分是Activity的话,它庞大的根须就是Service。Android的服务组件没有运行在独立的进程或线程中,它和其他的组件一样也在应用的主线程中运行,如果服务组件执行比较耗时的操作就会导致主线程阻塞或者假死,从而无法响应用户的操作。
2、从使用的角度来讲:
Service不仅可以给Activity建立双向连接,为Activity提供数据和功能支持,也可以单向接受Intent的请求,进行数据的分析处理和功能调度。
3、从扮演的角色来讲:
Activity的功能比较单一,主要就是显示应用所具有的一些功能,帮助用户与应用进行交互,像一个人的脸。而Service可能扮演功能调度者也能扮演功能提供者,从触发器收集信息进行分析和处理,然后更新界面,修改数据或进行其他操作时是一个功能调度者,从输入法的选择考虑Service扮演的就是一个功能提供者。View组件是Android中用户能够实实在在看到的部分,如按钮,输入框等就是继承自这个类,View只有装入Activity这样的容器中才有意义,而反过来
Activity装入了这些View后才能够成功完成与用户交互的任务,但是Service不需要这些花哨的东西,只需要默默地等待事件发生或者听候差遣。
Enviroment对象:
Environment 是一个提供访问环境变量的类。Environment 包含常量:
常量
MEDIA_BAD_REMOVAL
解释:返回getExternalStorageState() ,表明SDCard 被卸载前己被移除
MEDIA_CHECKING
解释:返回getExternalStorageState() ,表明对象正在磁盘检查。
MEDIA_MOUNTED
解释:返回getExternalStorageState() ,表明对象是否存在并具有读/写权限
MEDIA_MOUNTED_READ_ONLY
解释:返回getExternalStorageState() ,表明对象权限为只读
MEDIA_NOFS
解释:返回getExternalStorageState() ,表明对象为空白或正在使用不受支持的文件系统。
MEDIA_REMOVED
解释:返回getExternalStorageState() ,如果不存在 SDCard 返回
MEDIA_SHARED
解释:返回getExternalStorageState() ,如果 SDCard 未安装 ,并通过 USB 大容量存储共享 返回
MEDIA_UNMOUNTABLE
解释:返回getExternalStorageState() ,返回 SDCard 不可被安装 如果 SDCard 是存在但不可以被安装
MEDIA_UNMOUNTED
解释:返回getExternalStorageState() ,返回 SDCard 已卸掉如果 SDCard 是存在但是没有被安装
Environment 常用方法:
方法:getDataDirectory()
解释:返回 File ,获取 Android 数据目录。
方法:getDownloadCacheDirectory()
解释:返回 File ,获取 Android 下载/缓存内容目录。
方法:getExternalStorageDirectory()
解释:返回 File ,获取外部存储目录即 SDCard
方法:getExternalStoragePublicDirectory(String type)
解释:返回 File ,取一个高端的公用的外部存储器目录来摆放某些类型的文件
方法:getExternalStorageState()
解释:返回 File ,获取外部存储设备的当前状态
方法:getRootDirectory()
解释:返回 File ,获取 Android 的根目录
讲述 StatFs 类
StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况
StatFs 常用方法:
getAvailableBlocks()
解释:返回 Int ,获取当前可用的存储空间
getBlockCount()
解释:返回 Int ,获取该区域可用的文件系统数
getBlockSize()
解释:返回 Int ,大小,以字节为单位,一个文件系统
getFreeBlocks()
解释:返回 Int ,该块区域剩余的空间
restat(String path)
解释:执行一个由该对象所引用的文件系统