单元测试_Logcat_数据保存(手机内-sdcard)_文件权限_SharedPreferences_生成xml及pull解析总结
一、了解测试相关概念
好的软件不是写出来, 测出来的.
1、根据测试的时候 是否有源代码:
白盒测试: 写测试代码 测试源代码里面的业务方法
黑盒测试: 不知道源代码, 测试应用程序的业务逻辑.
2、根据测试的粒度
方法测试 function test
单元测试 unit test
junit测试框架
集成测试 integration test
系统测试 system test
3、根据测试的暴力程度
冒烟测试 smoke test
压力测试 pressure
test android压力测试:-->adb shell
-->monkey 5000
测试是用来测试service中的业务方法 |
二、掌握android下junit单元测试
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.action“ android:versionCode="1“ android:versionName="1.0">
<application
android:icon="@drawable/icon" android:label="@string/app_name">
<uses-library android:name="android.test.runner" />
....
</application>
<uses-sdk
android:minSdkVersion="6" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="cn.itcast.action" android:label="Tests for
My App" />
</manifest>
|
三、掌握logcat的使用
logcat 分5个等级:
verbose 啰嗦(尽可能多的显示) 黑色
debug 调试
蓝色
info 信息
绿色
warn 警告
橙色
error 错误
红色
assert (级别最高)
选择verbose,所有的log都会显示出来,error只会显示error错误
SSystem.out和System.err输出的信息也会显示在LogCat中,
注意System.out输出信息是Info级别,
System.err是Warn级别
Log.v(tag,msg) 其中tag一般为当前类名
Log.w(tag,msg) //warn
Log.wtf(tag,msg)//assert
对于service业务层的异常,一般抛出去,否则调用者不知道,而对于有返回值的service中方法,也可以捕获.
四、掌握android下文件的读写 和 掌握android
sd卡文件的操作
1、读写在ROM
a)
手写FileInputStream/FileOutputStream
b) openFileOutput(filename,mode)
文件保存在/data/data/<package name>/files目录
第一参数用于指定文件名称,不能包含路径分隔符“/”
,如果文件不存在,Android 会自动创建它
第二参数用于指定操作模式
Context.MODE_PRIVATE = 0
Context.MODE_APPEND = 32768
Context.MODE_WORLD_READABLE = 1
Context.MODE_WORLD_WRITEABLE = 2
Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;
MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
c)openFileInput(filename);
打开存放在/data/data/<package name>/files目录应用私有的
d)对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限
openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE +
Context.MODE_WORLD_WRITEABLE);
e)getCacheDir()和getFilesDir()
getCacheDir()方法用于获取/data/data/<package
name>/cache目录 缓存数据,在内部空间不足会被清除,也可以手动
getFilesDir()方法用于获取/data/data/<package
name>/files目录 用户数据,配置
2、读写在SDcard
Environment.getExternalStorageDirectory()方法用于获取SDCard的目录 获取/mnt/sdcard目录
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED
<!-- 往SDCard写入数据权限
-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 在SDCard中创建与删除文件权限
-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
注意:对于Android4.0,如果用户勾选了"对SD卡进行读写保护",那么读取SDcard也需要权限:
android.permission.READ_EXTERNAL_STORAGE
五、熟悉读取系统源代码的技巧
ctrl+h
六、掌握sharedpreference的使用
1、使用SharedPreferences进行数据存储
(适合用于保存软件配置参数)
其背后是用xml文件存放数据,文件存放在/data/data/<package
name>/shared_prefs目录下
获取:SharedPreferences sharedPreferences =
context.getSharedPreferences("itcast",
Context.MODE_PRIVATE);
getSharedPreferences(name,mode)方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由Android自动加上。方法的第二个参数指定文件的操作模式,共有四种操作模式,这四种模式前面介绍使用文件方式保存数据时已经讲解过。如果希望SharedPreferences背后使用的xml文件能被其他应用读和写,
另外Activity还提供了另一个getPreferences(mode)方法操作SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
SharedPreferences sharedPreferences = getSharedPreferences("itcast", Context.MODE_PRIVATE);
Editor editor
= sharedPreferences.edit();//获取编辑器
editor.putString("name", "传智播客");
editor.putInt("age", 4);
editor.commit();//提交修改--一定要提交
2、访问SharedPreferences中的数据
SharedPreferences sharedPreferences =
getSharedPreferences("itcast", Context.MODE_PRIVATE);
//getString()第二个参数为缺省值,如果preference中不存在该key,将返回缺省值
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 1);
3、访问其他应用的SharedPreferences数据(前提是该preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限)
通过Context 访问preference
,访问preference时会在应用所在包下的shared_prefs目录找到preference
Context otherAppsContext =
createPackageContext("cn.itcast.action", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences =
otherAppsContext.getSharedPreferences("itcast", Context.MODE_WORLD_READABLE);
String name =
sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age",
0);
如果不通过创建Context访问其他应用的preference,也可以以读取xml文件方式直接访问其他应用preference对应的xml文件,如:
File xmlFile = new File(“/data/data/<package
name>/shared_prefs/itcast.xml”);//<package name>应替换成应用的包名
七、掌握xml文件的序列化
1、手动生成xml
2、使用XmlSerializer序列化文件
// 1,初始化一个xml文件的序列化器
XmlSerializer xSerializer = Xml.newSerializer();
// 2.初始化序列器参数
File file = new File(Environment.getExternalStorageDirectory(),"smsinfo.xml");
FileOutputStream fos = new FileOutputStream(file);
xSerializer.setOutput(fos, "utf-8");
// 3.开始写xml文件.
xSerializer.startDocument("utf-8", true);
xSerializer.startTag(null, "smss");
xSerializer.startTag(null, "body");
xSerializer.text("</body>" + smsInfo.getBody());
xSerializer.endTag(null, "body");
八、掌握采用pull解析器解析xml文件
1、解析xml
/**
* 天气预报解析
*/
public class WeatherService {
public static List<Channel> getAllWeatherInfos(InputStream in)
throws XmlPullParserException, IOException {
List<Channel> lChannels = null;
Channel channel = null;
// 1、new一个解析器
XmlPullParser parser = Xml.newPullParser();
// 2.设置xml解析器的参数
parser.setInput(in, "utf-8");
// 3.开始解析xml文件.
int eventType = parser.getEventType();// 获取当前的事件的类型
while (eventType != XmlPullParser.END_DOCUMENT) { // 需要让pull解析器解析到文件的末尾
String nodeName = parser.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if ("weather".equals(nodeName)) {// 总的开始节点
lChannels = new ArrayList<Channel>(); // 初始化集合
} else if ("channel".equals(nodeName)) { // 某个城市的信息开始了.
channel = new Channel();
String id = parser.getAttributeValue(null, "id");
channel.setId(Integer.parseInt(id));
} else if ("city".equals(nodeName)) {// 城市开始
String city = parser.nextText();
channel.setCity(city);
} else if ("temp".equals(nodeName)) {
String temp = parser.nextText();
channel.setTemp(temp);
} else if ("wind".equals(nodeName)) {
String wind = parser.nextText();
channel.setWind(wind);
} else if ("pm250".equals(nodeName)) {
String pm250 = parser.nextText();
channel.setPm250(Integer.parseInt(pm250));
}
break;
case XmlPullParser.END_TAG:
if ("channel".equals(nodeName)) {// 一个channel结束了
lChannels.add(channel);
channel = null;
}
break;
}
eventType = parser.next();
}
return lChannels;// 把所有的频道的集合返回回去
}
}
2、生成XML文件
public static String writeXML(List<Person> persons, Writer writer){
XmlSerializer serializer = Xml.newSerializer();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
//第一个参数为命名空间,如果不使用命名空间,可以设置为null
serializer.startTag("", "persons")
;
for (Person person : persons){
serializer.startTag("", "person");
serializer.attribute("", "id", person.getId().toString());
serializer.startTag("", "name");
serializer.text(person.getName());
serializer.endTag("", "name");
serializer.startTag("", "age");
serializer.text(person.getAge().toString());
serializer.endTag("", "age");
serializer.endTag("", "person");
}
serializer.endTag("", "persons");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
九、掌握android下debug断点调试
F5:进入F6:跳过 F8:放行
如果真是手机不能调试,在AndroidManifest.xml中配置:
断点调试
分析pull解析xml文件解析的流程
十、掌握android下文件访问权限 掌握android下和linux下的文件访问权限
linux下面权限:rwx 4 2
1