M播放器项目实践.docx
《M播放器项目实践.docx》由会员分享,可在线阅读,更多相关《M播放器项目实践.docx(49页珍藏版)》请在冰豆网上搜索。
M播放器项目实践
Mp3播放器项目
项目功能简介:
环境配置:
服务器:
tomcat
XML文件:
resources.xml(用来记录服务器中所有歌曲信息)
Mp3文件和LRC文件
1、将resources.xml文件、Mp3文件和LRC文件都放置到tomcat-----webapps----Mp3.
2、在tomcat-----webapps----Mp3中建立WEB-INF文件夹(添加配置文件web.xml)
3、在eclipse中启动tomcat,并在浏览器中实验是否能正确访问到以上文件
()
注意:
每次启动eclipse后要运行这个程序的话,别忘了启动tomcat啊!
否则读取不了服务器中的Mp3列表的。
第一集:
实现Mp3文件列表的显示--------点击menu-------出现更新列表按钮,点击更新列表按钮,可以显示服务器中所有的歌曲信息
功能分解:
1、menu按钮显示
2、从服务器下载resources.xml
3、用SAX方法解析resources.xml:
①ContentHandler类的设计;
②SAX解析;
功能实现:
1、创建类Mp3ListActivity
重写回调函数publicbooleanonCreateOptionsMenu(Menumenu){}
实现menu按钮显示功能:
publicbooleanonCreateOptionsMenu(Menumenu){
returnsuper.onCreateOptionsMenu(menu);
}
注意点:
在类中,元素的ID最好定义一个常量来代替实际的int型数据,以便修改。
如:
UPDATEABOUT
2、创建HttpDownloader类,实现xml文本文件的下载功能:
import.*;
importjava.io.*;
publicclassHttpDownloader{
publicInputStreamgetInput(URLurl){
HttpURLConnectionhttpconn=null;
InputStreaminput=null;
try{
httpconn=(HttpURLConnection)url.openConnection();
input=httpconn.getInputStream();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returninput;
}
publicStringtextDownload(StringurlStr){
URLurl;
InputStreaminput=null;
StringBuffersb=newStringBuffer();
Stringline=null;
BufferedReaderbuffer=null;
try{
url=newURL(urlStr);
input=getInput(url);
buffer=newBufferedReader(newInputStreamReader(input,"gb2312"));
while((line=buffer.readLine())!
=null){
sb.append(line);
}
//注意:
此处一定要用一个line进行append,否则会读取数据不完整
//注意:
记得将InputStreamReader中的编码设置为"gb2312",否则不可读取中文
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
buffer.close();
}catch(Exceptione){
e.printStackTrace();
}
}
returnsb.toString();
}
}
注意:
要在AndroidManifest中添加访问internet的权限:
3、创建Mp3ListContentHandler类,实现ContentHandler类的设计,以便xml的解析用。
4、在解析resources.xml时,将每一个Mp3看做一个
对象,即:
....之间子元素是这个Mp3对象中的私有变量。
因此还需要创建一个Mp3Info类,以实现在xml文件解析过程中对每个Mp3的属性进行存储:
publicclassMp3Info{
privateStringid;
privateStringmp3Name;
privateStringmp3Size;
privateStringlrcName;
privateStringlrcSize;
/**
*直接右击然后source选择生成get和set方法以及toString方法以及构造函数(带参数和不带参数的构造函数)
*@return
*/
publicMp3Info(){
super();
}
publicMp3Info(Stringid,Stringmp3Name,Stringmp3Size,StringlrcName,
StringlrcSize){
super();
this.id=id;
this.mp3Name=mp3Name;
this.mp3Size=mp3Size;
this.lrcName=lrcName;
this.lrcSize=lrcSize;
}
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicStringgetMp3Name(){
returnmp3Name;
}
publicvoidsetMp3Name(Stringmp3Name){
this.mp3Name=mp3Name;
}
publicStringgetMp3Size(){
returnmp3Size;
}
publicvoidsetMp3Size(Stringmp3Size){
this.mp3Size=mp3Size;
}
publicStringgetLrcName(){
returnlrcName;
}
publicvoidsetLrcName(StringlrcName){
this.lrcName=lrcName;
}
publicStringgetLrcSize(){
returnlrcSize;
}
publicvoidsetLrcSize(StringlrcSize){
this.lrcSize=lrcSize;
}
@Override
publicStringtoString(){
return"Mp3Info[id="+id+",mp3Name="+mp3Name+",mp3Size="
+mp3Size+",lrcName="+lrcName+",lrcSize="+lrcSize
+"]";
}
}
注意点:
在编程中,对于这种专门用于存储某种实体对象的属性的类,都可用上面这种方法进行处理:
①将每个属性定义为一个私有变量;
②利用eclipse自动生成get函数、set函数和构造函数的功能,生成所需函数
③利用eclipse自动生成toString函数,以便调试使用
5、创建Mp3ListContentHandler类,以便设置SAX解析时的Handler:
publicclassMp3ListContentHandlerextendsDefaultHandler{
privateMp3Infomp3info=null;
privateListinfos=null;//用于存放各个的Mp3对象
privateStringtagName=null;
publicListgetInfos(){
returninfos;
}
publicvoidsetInfos(Listinfos){
this.infos=infos;
}
publicMp3ListContentHandler(Listinfos){
super();
this.infos=infos;
}
@Override
publicvoidcharacters(char[]ch,intstart,intlength)
throwsSAXException{
Stringtemp=newString(ch,start,length);
if(tagName.equals("id")){
mp3info.setId(temp);
}
elseif(tagName.equals("mp3.name")){
mp3info.setMp3Name(temp);
}
elseif(tagName.equals("mp3.size")){
mp3info.setMp3Size(temp);
}
elseif(tagName.equals("lrc.name")){
mp3info.setLrcName(temp);
}
elseif(tagName.equals("lrc.size")){
mp3info.setLrcSize(temp);
}
}
//每解析到的endElement时,表示一个Mp3对象解析完成,故将这个mp3info对象放到infos中
@Override
publicvoidendElement(Stringuri,StringlocalName,StringqName)
throwsSAXException{
if(localName.equals("resource")){
infos.add(mp3info);
}
tagName="";
}
@Override
//每解析到一个的startElement时候,表示一个新的Mp3对象将被解析到,故创建新的Mp3Info对象来存储Mp3对象
publicvoidstartElement(Stringuri,StringlocalName,StringqName,
Attributesattributes)throwsSAXException{
tagName=localName;
if(tagName.equals("resource")){
mp3info=newMp3Info();
}
}
@Override
publicvoidendDocument()throwsSAXException{
//TODOAuto-generatedmethodstub
super.endDocument();
}
@Override
publicvoidstartDocument()throwsSAXException{
//TODOAuto-generatedmethodstub
super.startDocument();
}
}
6、在Mp3ListActivity类中添加解析xml的方法:
privateListparse(StringxmlStr){
SAXParserFactoryfactory=SAXParserFactory.newInstance();
XMLReaderreader;
Listinfos=null;
try{
reader=factory.newSAXParser().getXMLReader();
infos=newArrayList();
Mp3ListContentHandlermp3listhandler=newMp3ListContentHandler(infos);
reader.setContentHandler(mp3listhandler);
reader.parse(newInputSource(newStringReader(xmlStr)));
//使用迭代器Iterator遍历infos中的各个Mp3对象,快捷键:
输入for以后//按下alt+/
for(Iteratoriterator=infos.iterator();iterator.hasNext();){
Mp3Infomp3info=(Mp3Info)iterator.next();
}
}catch(SAXExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(ParserConfigurationExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returninfos;
}
7、调用上述方法和各个类,实现点击更新列表按钮来读取服务器中resources.xml文件中各个Mp3信息的功能,在Mp3ListActivity类中添加以下两个方法:
publicbooleanonOptionsItemSelected(MenuItemitem){
if(item.getItemId()==UPDATE){
parse(xml);
}
elseif(item.getItemId()==ABOUT){
//点击关于
}
returnsuper.onOptionsItemSelected(item);
}
privateStringdownloadXML(StringurlStr){
HttpDownloaderhttpdownloader=newHttpDownloader();
Stringresult=httpdownloader.textDownload(urlStr);
returnresult;
}
8、利用ListView的知识,将得到的mp3infos的相关信息显示在ListActivity中。
在Mp3ListActivity类的点击更新列表的相应事件中添加如下代码。
另外,新建main.xml和mp3info_item.xml来布局ListActivity
publicbooleanonOptionsItemSelected(MenuItemitem){
if(item.getItemId()==UPDATE){
//点击更新列表
Listinfos;
ArrayList>list=newArrayList>();
infos=parse(xml);
for(Iteratoriterator=infos.iterator();iterator.hasNext();){
Mp3Infomp3Info=(Mp3Info)iterator.next();
HashMapmp3=newHashMap();
mp3.put("mp3_name",mp3Info.getMp3Name());
mp3.put("mp3_size",mp3Info.getMp3Size());
list.add(mp3);
}
SimpleAdaptersimple=
newSimpleAdapter(this,list,
{"mp3_name","mp3_size"},newint[]
setListAdapter(simple);
}
elseif(item.getItemId()==ABOUT){
//点击关于
}
returnsuper.onOptionsItemSelected(item);
}
Main.xml:
xmlversion="1.0"encoding="utf-8"?
>
android:
orientation="vertical"
android:
layout_width="fill_parent"
android:
layout_height="fill_parent"
>
android:
id="@android:
id/list"
android:
orientation="vertical"
android:
layout_width="fill_parent"
android:
layout_height="wrap_content"
android:
drawSelectorOnTop="false"
/>
Mp3info_item.xml:
xmlversion="1.0"encoding="utf-8"?
>
android:
layout_width="fill_parent"
android:
layout_height="fill_parent"
android:
orientation="horizontal"
android:
paddingLeft="10dip"
android:
paddingRight="10dip"
android:
paddingTop="1dip"
android:
paddingBottom="1dip">
android:
id="@+id/mp3_name"
android:
layout_width="wrap_content"
android:
layout_height="30dip"
android:
textSize="10pt"
/>
android:
id="@+id/mp3_size"
android:
layout_width="fill_parent"
android:
layout_height="fill_parent"
android:
gravity="right"
android:
textSize="10pt"
/>
编程思想:
实现相应的功能只是很小的一部分,对代码进行重构是很重要的一部分工作!
重构:
提高代码的可复用性,减少重复性代码,提高代码的可扩展性,以便以后代码的修改和功能的扩展。
函数越小越好!
重构Mp3ListActivity类中的函数,将回调函数中繁杂的功能实现函数封装成单独的函数,在回调函数中直接调用,最终得到Mp3ListActivity类的代码如下:
import.*;
importjava.util.*;
importjavax.xml.*;
publicclassMp3ListActivityextendsListActivity{
privatestaticfinalintUPDATE=1;
privatestaticfinalintABOUT=2;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
updateListView();
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
returnsuper.onCreateOptionsMenu(menu);
}
privateSimpleAdapterbuildSimpleAdapter(Listmp3infos){
ArrayList>list=newArrayList>();
for(Iteratoriterator=mp3infos.iterator();iterator.hasNext();){
Mp3Infomp3Info=(Mp3Info)iterator.next();
HashMapmp3=newHashMap();
mp3.put("mp3_name",mp3Info.getMp3Name());
mp3.put("mp3_size",mp3Info.getMp3Size());
list.add(mp3);
}
SimpleAdaptersimple=
newSimpleAdapter(this,list,
{"mp3_name","mp3_size"},newint[]
returnsimple;
}
privatevoidupdateListView(){
//注意:
1、tomcat服务器中文件放置:
在webapps下新建Mp3文件,在Mp3文件中新建配置文件WEB-INF
//在Mp3文件中放置