一 数据格式xml&json入门与解析

 

一 单元测试方法

https://blog.csdn.net/yingaizhu/article/details/80297087

1.1  添加单元测试依赖包

    在程序模块下面的build.gradle中需要引入的依赖包:一般Androidstudio新建项目就会自动生成

testImplementation-引入的依赖是java unit单元测试,是运行在当前电脑的jvm上的单元测试;

androidTestImplementation-引入的依赖是Android单元测试,是运行在Android环境的单元测试。

1.2 添加测试代码目录

    如果AndroidStudio当前项目视图为Android,需要切换为Project视图,在程序模块下面的src目录下添加androidTest/java(Android单元测试,运行在Android环境的单元测试)和test/java(JUnit单元测试,运行在当前电脑的jvm上的单元测试),然后在里面添加包名和测试类。

 

 

 

  • androidTest/java(Android单元测试,运行在当前电脑的jvm上的单元测试,执行测试的时候需要Android连接设备,速度比较慢,适合需要调用Android api的单元测试)
  • test/java(JUnit单元测试,用来放不需要Android依赖的单元测试类,运行在当前电脑的jvm上的单元测试,速度快,适合只是对java代码功能进行单元测试)

1.3 添加单元测试类

1.3.1手动编写单元测试类

1.3.1.1  androidTest测试类

    androidTest测试类适用于需要依赖Android api的单元测试,需要连接Android设备才能进行测试。新建的androidTest java类需要添加@RunWith(AndroidJUnit4.class)注解,类的方法如果是测试入口方法需要添加@Test注解。
示例代码:路径 app\src\androidTest\java\com\example\itandroid_1

public class MainActivityTest {

    private Context mTargetContext;

    @Before
    public void setUP() throws Exception {
        mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
    }

    @Test
    public void onCreate() {
        try {
            ApplicationInfo applicationInfo = mTargetContext.getPackageManager().getApplicationInfo(mTargetContext.getPackageName(), PackageManager.GET_META_DATA);
            Bundle metaData = applicationInfo.metaData;
            String data = metaData.getString("com.panzq.Androidtest");
            assertEquals("123456", data);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }

}

1.3.1.2  test测试类

    test测试类适用于纯java的单元测试,运行于当前设备的jvm环境中,无需Android设备即可测试。新建test java类,类的方法如果是测试入口方法需要添加@Test注解。
代码示例:路径app\src\test\java\com\example\itandroid_1
public class TestUtil {
    @Before
    public void setUp() throws Exception {

    }

    @Test
    public void isEmpty() {
        assertEquals(true, TextUtils.isEmpty(""));
    }
}

 

1.3.1.3 测试类中的setUp方法

    在测试类中的setUp方法,可以在启动测试前进行一些初始化,比如测试类中的变量等初始化,这个方法需要添加@Before注解。

说明:
上面的示例代码中可以直接使用assertEquals,是因为使用了静态import方法引入了相应的包(import static org.junit.Assert.*;)
根据测试的功能合理使用androidTest和test,提高单元测试效率。
2.2 自动生成测试类和测试方法
        上面介绍的是手动添加测试类和测试方法,以下介绍自动生成测试类和方法。在项目源码中选中需要添加单元测试的类并打开,在内容显示区域“右键”->“Go To”,在弹出窗口中选择“Test”,在弹出窗口中选择“Create New Test ......”

 

 

 在接下来弹出的对话框中,勾选需要添加单元测试的方法,在这里有个“Generate”通用方法生成,可以选择setUp/@Before(启动前调用,可用于初始化)和tearDown/@After(结束后调用)

 

 

1.3 运行单元测试

1.3.1 运行单个测试方法

    在测试方法题内部,“右键”,在弹出菜单中选择“Run 方法名”即可(单元测试也可以使用断点调试和性能调试)。

 

 

1.3.2 批量运行测试方法(有些情况下可能会无法实现)    

  在终端使用gradle运行test任务,可以执行所有的单元测试方法(在AndroidStudio的Terminal运行gradlew test,在系统终端中运行gradle -p 项目路径 test,gradle没有配置环境变量,需要绝对路径),运行完成后,就会运行所有的单元测试方法,并且会显示结果,如下图:

 

 

二 XML语法 

<?xml version ="1.0" encoding ="utf-8"?>
<中国>
    <北京>
        <昌平></昌平>
        <海淀></海淀>
    </北京>
</中国>

2.1文档声明

<?xml version ="1.0" encoding ="utf-8"?>文档声明必须写在第一行
保存的时候xml声明的编码要跟文件保存的编码保存一致,如果不声明编码默认utf-8

2.2 元素

<中国>
    <北京>
        <昌平></昌平>
        <海淀></海淀>
    </北京>
</中国>

 

2.3 属性

1.属性要写在开始标签中

2.属性的命名规则跟元素的命名规则一样

3.属性一定要用引号包起来,单引号双引号都可以

4.属性的内容可以用子标签形式表示

2.4 注释

<!-- 注释-->

CDATA 注释 可以包含大于小于号,不会被解析器解析

<![CDATA[<北京></北京>]]>

2.5 特殊字符 转义

特殊字符 特殊字符
& &amp;
< &lt;
> &gt;
" &quot;
' &apos;

 

2.6 shcema

https://www.w3school.com.cn/schema/schema_howto.asp

 

2.7 Dom 解析

 dom解析xml的优点:

  因为分配了一个树形结构,很方便的实现增加修改删除操作

dom解析xml的缺点

  如果要解析文件过大,一次性哎内存中分配一个树形结构,操作内存的溢出。

public class DomParseUtil {
    public void domParse() {
        //1.获取DocumentBuilderFactory
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        try {
            //2.获取DocumentBuilder
            DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
            //3.通过DocumentBuilder解析xml文档获得Document对象
            Document document = documentBuilder.parse("xml.xml");
            //4.通过元素的名字可以找到元素的集合
            NodeList nodeList = document.getElementsByTagName("书名");

            //获取节点个数nodeList.getLength();
            for (int i = 0; i < nodeList.getLength(); i++) {
                //5.找到第二个元素,第二个书名
                Node node = nodeList.item(1);
                //6.读取对应节点的文本内容
                String content = node.getTextContent();
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void domModifyXml() {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse("book.xml");
            NodeList nodeList = document.getElementsByTagName("售价");
            Node node = nodeList.item(1);
            node.setTextContent("99.00元");
            //修改xml中的内容,只有dom可以修改
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            Source xmlSource = new DOMSource(document);
            Result outputTarget = new StreamResult("book.xml");
            transformer.transform(xmlSource, outputTarget);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}

2.8 sax解析

  sax解析方式:边读边解析

使用sax方式督导特定的标签时候,自动调用相应的方式进行操作

sax解析xml的优点: 不会造成内存溢出

sax解析缺点:不能修改xml文件

public class SaxParseUtil {
    private MycontentHandler handler;
    private ArrayList<BookBean> books = new ArrayList<>();
    private String tag;
    private BookBean bookBean;

    public SaxParseUtil() {
        this.handler = new MycontentHandler();
    }

    public void saxParser() {
        //获取工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        try {
            SAXParser saxParser = saxParserFactory.newSAXParser();
            //获取xmlReader通过reader可以试着获取ContentHandler
            XMLReader xmlReader = saxParser.getXMLReader();
            //给xmlReader设置ContentHandler ContentHandler是一个接口,里面太多的方法没实现
            //不去直接实现ContentHandler而是继承它默认的实现DefaultHandler
            xmlReader.setContentHandler(handler);
            //开始解析文档 这里传入xml路径
            xmlReader.parse("book.xml");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class MycontentHandler extends DefaultHandler {
        @Override
        public void startDocument() throws SAXException {
            Log.d("panzq", "文档开始");

        }

        @Override
        public void endDocument() throws SAXException {
            Log.d("panzq", "文档开始");
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            Log.d("panzq", "开始标签" + qName);
            if ("书架".equals(qName)) {
                books = new ArrayList<>();
            } else if ("书".equals(qName)) {
                bookBean = new BookBean();
            } else if ("书名".equals(qName)) {
                tag = "书名";
            } else if ("作者".equals(qName)) {
                tag = "作者";
            } else if ("售价".equals(qName)) {
                tag = "售价";
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            Log.d("panzq", "结束标签" + qName);
            tag = null;
            if ("书架".equals(qName)) {
                for (BookBean bookBean : books) {
                    Log.d("panzq", "books : " + books);
                }
            } else if ("书".equals(qName)) {
                books.add(bookBean);
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            String text = new String(ch, start, length);//拿到具体的文本
            Log.d("panzq", "文本内容" + text);
            if (tag.equals("书名")) {
                bookBean.setTitle(text);
            } else if (tag.equals("作者")) {
                bookBean.setAuthor(text);
            } else if (tag.equals("售价")) {
                bookBean.setPrice(text);
            }
        }
    }

}

2.9 Pull 解析

 

public class PullParserUtil {

    public void pullTest() {
        try {
            //获取工厂
            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
            //获取xml的解析器
            XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
            //给解析器设置一个输入源
            //第一个参数输入流 第二个参数 文档用到的字符编码器
            xmlPullParser.setInput(new FileInputStream(new File("book.xml")), "utf-8");
            //获取当前事件类型
            int eventType = xmlPullParser.getEventType();

            ArrayList<BookBean> books = null;
            BookBean bookBean = null;
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_TAG:
                        //xmlPullParser.getName()获取当前事件对应的元素的名字
                        if ("书架".equals(xmlPullParser.getName())) {
                            //创建一个集合
                            books = new ArrayList<>();
                        } else if ("书".equals(xmlPullParser.getName())) {
                            //创建一个book对象
                            bookBean = new BookBean();
                        } else if ("书名".equals(xmlPullParser.getName())) {
                            //xmlPullParser.nextText()获取当前节点的下一个内容
                            bookBean.setTitle(xmlPullParser.nextText());
                        } else if ("作者".equals(xmlPullParser.getName())) {
                            bookBean.setAuthor(xmlPullParser.nextText());
                        } else if ("售价".equals(xmlPullParser.getName())) {
                            bookBean.setPrice(xmlPullParser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if ("书".equals(xmlPullParser.getName())) {
                            books.add(bookBean);
                        }
                        break;
                }
                //调用xmlPullParser.next()方法解析下一个元素,用这个结果来更新eventType如果解析到文档结束那么就会退出
                //如果不更新这个eventType就是死循环
                eventType = xmlPullParser.next();
            }
            
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

2.10 Json

 

public void JsonParser() {
        String jstring = "{'name':'张三','age':'20'}";
        try {
            JSONObject jsonObject = new JSONObject(jstring);
            String name = jsonObject.getString("name");
            int age = jsonObject.getInt("age");
            Log.d("panzq", "name = " + name + " , age = " + age);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String jsonArray="[{'name':'张三','age':'20'},{'name':'李四','age':'30'}]";
        try {
            JSONArray array = new JSONArray(jsonArray);
            for (int i=0;i<array.length();i++) {
                JSONObject jsonObject = array.getJSONObject(i);
                String name = jsonObject.getString("name");
                int age = jsonObject.getInt("age");
                Log.d("panzq", "name = " + name + " , age = " + age);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

 

 

 

 

 

 

posted @ 2019-11-10 09:31  强哥10732  阅读(342)  评论(0编辑  收藏  举报