从下午一直调试bug到现在,终于解决了问题!
今天主要做的是自己用tomcat配置了一个服务器,在服务器里放了一个xml文件,然后通过手机去下载这个文件,然后再解析出来。
遇到的第一个bug是无法下载文件,因为连接不上,tomcat服务器的地址是:http://127.0.0.1:8080/mp3/resources.xml ,即我在电脑浏览器中输入这个地址能够访问这个文件,但是在andorid手机上访问这个文件时,需要使用电脑的ip地址。比如我的ip地址是:192.168.1.1 ,那么在访问服务器时使用的地址应该是:http://192.168.1.1:8080/mp3/resources.xml
第二个问题是:通过Ip地址获得文件的InputStream后,需要把输入流还原为文件(即写入到文件夹中)
刚开始我使用的是如下方式:
byte[] buffer = new byte[512];
while ((input.read(buffer)) != -1) {
output.write(buffer);
}
output.flush();
后来logcat老提示xml文件格式警告,通过File Explore导出下载的xml文件才发现文件的末尾多了很多空字符。这过程中还遇到另一个问题,就是导出文件的时候提示导出失败,后来把eclipse关了重启就好了。我明白了因为每个buffer的长度都是512字节,最后一次写buffer的时候,buffer中可能有空余的长度没有数据可写,因此多了空白字符。所以后来用了如下方式:就彻底解决了。这也得到一个经验,即以后写文件的时候,一定要用wirte(buffer,0,length)方法,而不要用write(buffer)方法。
byte[] buffer = new byte[512];
int length=0;
while ((length=input.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
output.flush();
第三个问题是解析xml的时候遇到的,如下:
<resources>
<resource>
<id>0001</id>
<mp3_name>You Can'T Always Get What You Want</mp3_name>
<mp3_size>7182702</mp3_size>
<lrc_name>You Can'T Always Get What You Want</lrc_name>
<lrc_size>2021</lrc_size>
</resource>
<resource>
<id>0002</id>
<mp3_name>そばにいるね-青山テルマ</mp3_name>
<mp3_size>4859626</mp3_size>
<lrc_name>そばにいるね-青山テルマ</lrc_name>
<lrc_size>4151</lrc_size>
</resource>
<resource>
<id>0003</id>
<mp3_name>青山黛玛</mp3_name>
<mp3_size>4993259</mp3_size>
<lrc_name>青山黛玛</lrc_name>
<lrc_size>1615</lrc_size>
</resource>
</resources>
java代码部分:
public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
if(localName.equals("id")){
currentState=ID;
return;
}
if(localName.equals("mp3_name")){
currentState=MP3NAME;
return;
}
if(localName.equals("mp3_size")) {
currentState=MP3SIZE;
return;
}
if(localName.equals("lrc_name")) {
currentState=LRCNAME;
return;
}
if(localName.equals("lrc_size")) {
currentState=LRCSIZE;
return;
}
}
@Override
public void characters(char[] ch,int start,int length)throws SAXException{
String charact = new String(ch,start,length);
switch (currentState) {
case ID:
musicInfo.setId(charact);
break;
case MP3NAME:
musicInfo.setMp3_name(charact);
break;
case MP3SIZE:
musicInfo.setMp3_size(Long.parseLong(charact));
break;
case LRCNAME:
musicInfo.setLrc_name(charact);
break;
case LRCSIZE:
musicInfo.setLrc_size(Long.parseLong(charact));
default:
break;
}
}
@Override
public void endElement(String uri,String localName,String qName)throws SAXException{
currentState=0;
if(localName.equals("resource")){
musicList.add(musicInfo);
}
}
如上,解析xml标签的时候,定义了一个全局变量currentState ,在startElement中,每当遇到一个标签就给currentState一个对应的值,这样在character方法中,通过判断现在currentSate的值就可以获取相应标签的属性。而在endElement方法中,一定要将currentState的值还原为0。假如不做这一步,那么当第一个resource标签解析完的时候,currentState的值会是LRCSIZE,当开始解析第二个resource标签的时候,在character方法中会响应case
LRCSIZE,resource的属性无法转换为Long类型,所以在musicInfo.setLrc_size(Long.parseLong(charact));
的时候会造成数据类型转换异常。实际上是整个逻辑错误,所以一定要记得在标签解析完时将currentState赋值为0。
以上就是今天的全部收获,希望能再接再厉。