最近学校组织做实训,分到的任务是做Android的天气预报软件,我分到的任务是制作生活小贴士的部分。主要是关于空气质量、洗车指数一类的信息的显示,我使用的API是新浪天气的API,新浪天气的API提供的主要是XML文件。
新浪天气API的介绍我主要是参考,这个博客讲解的很细致,网络上关于新浪天气大多都跟这个博客的类似。
API接口如下:
?city=%B1%B1%BE%A9&password=DJOYnieT8234jlsK&day=0
其中,city后的城市转码。
Password固定
Day为0表示当天天气,1表示第二天的天气,2表示第三天的天气,以此类推,最大为4。
city后的城市转码这句很笼统,为难了我一阵,在这里分享一下,这个转码需要使用GB2312来转换,就是类似
String city = java.net.URLEncoder.encode("北京","gb2312");
这样就可以直接转为我们需要的城市的转码。
接下来是关于解析XML文件,我使用的是XmlPullParser的方法解析。
1. 实例化一个XML解析器XmlPullParser
2. 给实例化的XML解析器所需要的xml资源
如:XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "UTF-8");
(is是从网络上获取的InputStream的字符流)
以上,XML解析器就获取了需要解析的XML文件。
接下来就是要解析获取的XML数据。
1. 得到XML标签
2. 通过循环语句对标签进行遍历获取想要的数据
例如:XML文件示例如下:
<Students>
<Student>
<id>1001</id>
<name>zhangsan</name>
</Student>
<Student>
<id>1002</id>
<name>lisi</name>
</Student>
</Students>
上面的解析器得到xml数据之后,解析的过程如下:
int type = parser.getEventType(); // 得到xml数据的标签
// 循环语句进行遍历
while(type != parser.END_DOCUMENT) // 在xml的标签不为结束标签时进行遍历,就是上面的</Students>标签
{
switch(type){// 判断标签类型,这个标签的数值我们可以从Android导入的包中查询到,以下提供一些常用的
// START_DOCUMENT:0END_DOCUMENT:1 START_TAG:2END_TAG:3 TEXT:4
case XmlPullParser.START_DOCUMENT: // START_DOCUMENT指一个实例的的开始标签,即<Student>
// 你的代码
break;
case XmlPullParser.START_TAG:// START_TAG指一个标签的开始,即<id>和<name>
// 一般在这个case中获取数据, 例如:
String name = parser.getName();// 获取标签标题
if(name.equals("id"))
{
System.out.println(parser.nextText());// parser.nextText()这个语句表示获取标签中的内容
}
if(name.equals("name"))
{
System.out.println(parser.nextText());
}
break;
case XmlPullParser.END_TAG:// END_TAG指一个标签的结束,即</id>和</name>
break;
}
parser.next();// 解析器移向下一个标签
type = parser.getEventType();// 获取标签类型
}
这样一个xml就解析结束了。
以下是我今天出现的BUG以及调试的结果,与君共勉。
BUG1:我在每一个case里向两个数据包里传递了数据,都是使用的parser.nextText()语句进行获取数据并传递。
只有第一个数据包接收到了第一个数据,其他数据都没有显示。
这个BUG我调试了一个下午才发现问题,所以一定要记录下来。
问题就在于parser.nextText()不能连续对一个标签使用两次。在发现问题之后,我对XmlPullParser的理解是,这个类实例化之后是个类似于指针的东西,这个东西只能向下运动和读取数据,因此我执行的第二次parser.nextText()操作使这个指针指向了一个未知的地方。
因此我们需要使用该数据时,可以先String temp = parser.nextText();然后可以多次调用temp这个变量。
BUG2:我们再解析数据的之后,很多时候是要把数据放入ListView控件中,但是很多时候他人为我们提供的XML文件的顺序是乱的。
(当然JSON数据不会出现这种解析乱掉的问题,所以如果有JSON数据的接口还是比较建议使用JSON数据)
下面我举个例子:例如我需要最近3天的天气信息和温度信息,而接口中提供的XML文件是3天的天气信息放在前3行,3天的温度信息放在后3行,当我们需要使用HashMap类的3个map实例来获取信息并放入ArrayList时就无法像很多的例子中那样直接使用循环,一个map里应该放入一个天气信息和一个温度信息,但是一个在第1遍循环,一个在第4遍循环,会造成map放入list的混乱。
这种问题我提供一下我的解决方法,并不是最好的甚至有些麻烦,如果各位看官有更好的方法欢迎一同交流。