[android] 11_单元测试_Logcat_数据保存(手机内-sdcard)_文件权限_SharedPreferences_生成xml及pull解析总结

Android 4.0

单元测试_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中的业务方法

二、掌握androidjunit单元测试

<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.outSystem.err输出的信息也会显示在LogCat中,

 

    注意System.out输出信息是Info级别,

       System.errWarn级别

 

    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