我一直在尝试为SAX解析器设置UI线程和处理程序。这是我的解析器没有实现UI线程和处理程序:
public class AndroidXMLReader extends ListActivity {
private XMLFeed myXMLFeed = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
URL xmlUrl = new URL("http://feeds.bbci.co.uk/news/uk/rss.xml");
SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
XMLReader myXMLReader = mySAXParser.getXMLReader();
XMLHandler myXMLHandler = new XMLHandler();
myXMLReader.setContentHandler(myXMLHandler);
InputSource myInputSource = new InputSource(xmlUrl.openStream());
myXMLReader.parse(myInputSource);
myXMLFeed = myXMLHandler.getFeed();
}
catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (myXMLFeed!=null)
{
ArrayAdapter<XMLItem> adapter =
new ArrayAdapter<XMLItem>(this,
android.R.layout.simple_list_item_1,myXMLFeed.getList());
setListAdapter(adapter);
}
}
}
然后在这里我去尝试添加UI线程&amp;处理程序。 编辑1 - 根据HellBoy的回复,这是修改后的代码:
public class AndroidXMLReader extends ListActivity {
private static final int THREAD_FINISHED = 0;
private XMLFeed myXMLFeed = null;
private ProgressDialog progressDialog;
private Button refreshFeed;
Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initControls();
}
public void initControls(){
refreshFeed = (Button) findViewById(R.id.refresh);
refreshFeed.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v){
progressDialog = ProgressDialog.show(AndroidXMLReader.this, "",
"Please wait for few seconds...", true);
processThread();
}
});
}
protected void processThread() {
Thread t = new Thread()
{
public void run(){
getNews();
//UI();
// Sends message to the handler so it updates the UI
handler.sendMessage(Message.obtain(mHandler, THREAD_FINISHED));
; }
};
t.start();
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case THREAD_FINISHED:
progressDialog.dismiss();
break;
};
};
};
private void getNews(){
try {
URL xmlUrl = new URL("http://feeds.bbci.co.uk/news/uk/rss.xml");
SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
XMLReader myXMLReader = mySAXParser.getXMLReader();
XMLHandler myXMLHandler = new XMLHandler();
myXMLReader.setContentHandler(myXMLHandler);
InputSource myInputSource = new InputSource(xmlUrl.openStream());
myXMLReader.parse(myInputSource);
myXMLFeed = myXMLHandler.getFeed();
}
catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (myXMLFeed!=null){
ArrayAdapter<XMLItem> adapter =
new ArrayAdapter<XMLItem>(this,
android.R.layout.simple_list_item_1,myXMLFeed.getList());
setListAdapter(adapter);
}
}
}
目前它挂在进度对话框中,我无法弄清楚为什么......任何帮助都将不胜感激。
编辑1 - 我现在收到的错误消息是:
只有创建视图层次结构的原始线程才能触及它 视图。
10-04 21:39:27.570: ERROR/AndroidRuntime(17454): at com.android.testfeed3.AndroidXMLReader.getNews(AndroidXMLReader.java:121)
10-04 21:39:27.570: ERROR/AndroidRuntime(17454): at com.android.testfeed3.AndroidXMLReader.access$2(AndroidXMLReader.java:85)
10-04 21:39:27.570: ERROR/AndroidRuntime(17454): at com.android.testfeed3.AndroidXMLReader$3.run(AndroidXMLReader.java:60)
10-04 21:39:27.645: WARN/ActivityManager(2703): Force finishing activity com.android.testfeed3/.AndroidXMLReader
10-04 21:39:33.495: ERROR/WindowManager(17454): Activity com.android.testfeed3.AndroidXMLReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40527a20 that was originally added here
10-04 21:39:33.495: ERROR/WindowManager(17454): android.view.WindowLeaked: Activity com.android.testfeed3.AndroidXMLReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40527a20 that was originally added here
10-04 21:39:33.495: ERROR/WindowManager(17454): at com.android.testfeed3.AndroidXMLReader$2.onClick(AndroidXMLReader.java:50)
任何帮助将不胜感激。
答案 0 :(得分:1)
尝试将您的processThread()方法设为这样
protected void processThread() {
Thread t = new Thread()
{
public void run() {
theThread();}
};
t.start();
}
答案 1 :(得分:1)
为了对UI进行更改,命令必须来自创建它的线程,即主(或UI)线程。
快速浏览一下,这一行:
if (myXMLFeed!=null)
{
ArrayAdapter<XMLItem> adapter =
new ArrayAdapter<XMLItem>(this,
android.R.layout.simple_list_item_1,myXMLFeed.getList());
setListAdapter(adapter);
}
需要放在一个单独的Handler中,Handler从你的新线程中调用。
答案 2 :(得分:0)
只需扫描您的代码,但我没有看到任何问题。您可以放置一些调试日志以查看哪条线卡住了。但如果我是你,我会使用AsynTask。
当您想要从后台线程更新UI时,线程和处理程序会派上用场。 当您触发阻止UI的内容时,将使用AsynTask。
在你的情况下,我认为AsynTask更好。
2)使用onPreExecute()(UI线程)来启动你想要的pregress对话框
3)在doInBackground()(工作线程)中进行实际的URL和SAX解析。这将在后台线程中为您运行代码,因此您不必初始化它。
4)onPostExecute()(UI线程),关闭对话框或执行任何想要更新UI的操作。
答案 3 :(得分:0)
等待!!这可能是什么?
protected void processThread() {
Thread t = new Thread();{ <--- a semi-colon
你可能想在线程't'中再次检查你的逻辑。