最近都在看Mars的视频跟着做Mp3播放器的项目,当中遇到不少问题。本文用以记录这些问题及其解决方法。
1、在新版的Android平台中,与网络相关的操作必须在Worker线程中运行,这意味着若想从网络获取数据后在UI中更新显示,就必须利用handler处理器来使Worker线程与主线程进行通讯。因此在Mars的代码中必须进行一些修改。主要代码如下。
当用户点击更新列表的菜单时,创建一个新的线程从服务器中获取XML配置文件,并把相关的数据对象封装给mp3Infos列表。此时,我们需要利用handler来发送一个Message给
主线程,让它更新界面中的列表项。
/**
* 更新列表显示
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == UPDATE){
//用户点击了更新列表按钮
new Thread(){
@Override
public void run() {
String xml = downloadXML("http://192.168.0.104:8080/mp3/resources.xml");
System.out.println("XML------>"+xml);
mp3Infos = parse(xml);
mySimpleAdapter = buildSimpleAdapter(mp3Infos);
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
}
}.start();
}
else if(item.getItemId() == ABOUT){
//用户点击了关于按钮
}
return super.onOptionsItemSelected(item);
}
然后我们在线程中生成一个MyHandler实例。当handler调用sendMessage()方法时,将同时调用handlerMessage()方法。我们只需要把与UI操作相关的代码写在handlerMessage()
方法体内即可。因为MyHandler的实例是在主线程生成的,它的方法体也运行在主线程中。
/**
* 该类继承Handler
* @author wangyubin
*
*/
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
//在这里进行UI操作,改变界面中的内容.
//当worker线程发送消息给主线程时将调用以下方法。
//更新列表界面
setListAdapter(mySimpleAdapter);
System.out.println("更新列表界面");
}