我这里的代码在2.3中一直有效,现在我们必须更新它,我收到很多错误,比如NetworkOnMainThreadException
。我想从我的Web服务中获取一个xml,将其关闭并将其解析为数组列表。这是代码
//Gets the xml from the url specified
String CallWebService(String url){
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
//Parses the xml to get DOM element
public Document GetDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
//Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
//Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
//Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
//Gets the child nodes of the xml
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if(child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE){
return child.getNodeValue();
}
}
}
}
return "";
}
我也有getChildElements
方法。问题是我打电话给这个方法。我曾经这样做过:
String serviceURL = "http://webservice.example.com/";
String xml = CallWebService(serviceURL);
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
但现在在4.1中我需要异步执行此操作而我不知道如何执行此操作。任何帮助将不胜感激。
修改
这就是我所拥有的线程无法启动
final String serviceURL = "urlString";
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == JOB_COMPLETE) {
String xml = (String) msg.obj;
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
}
super.handleMessage(msg);
}
};
Thread t = new Thread() {
@Override
public void run() {
String xml = CallWebService(serviceURL);
Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
msg.sendToTarget();
}
};
t.start();
修改
所以我尝试异步方式,它仍然无法正常工作。它根本没有击中GetDomElement。这是代码。
//I call this in my onCreate()
new getAppInfo().execute("http://webservice.example.com");
private class getAppInfo extends AsyncTask<String, Void, String> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected String doInBackground(String... urls) {
return CallWebService(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(String xml) {
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
}
}
答案 0 :(得分:0)
您必须实现AsyncTask:
http://developer.android.com/reference/android/os/AsyncTask.html
顺便说一下,这需要Android 3(如果我记得的话)。
我已在我的应用中实现了此功能,您可以在此处浏览我的代码:https://github.com/enrichman/roma-tre/blob/master/src/com/roma3/infovideo/utility/rss/RssTask.java
答案 1 :(得分:0)
答案 2 :(得分:0)
在活动onCreate中的主ui线程中定义一个处理程序,例如
private Handler mHandler;
private static int JOB_COMPLETE = 1;
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == JOB_COMPLETE) {
String xml = (String) msg.obj;
// do whatever you want with that string
}
super.handleMessage(msg);
}
};
然后在后台线程中运行所有长期工作
final String url = "...........";
Thread t = new Thread() {
@Override
public void run() {
String xml = CallWebService(url);
Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
msg.sendToTarget();
}
};
t.start();
答案 3 :(得分:0)
当应用程序尝试在其主线程上执行网络操作时引发的异常。
仅针对Honeycomb SDK或更高版本的应用程序进行此操作。针对早期SDK版本的应用程序可以在其主要事件循环线程上进行网络连接,但是非常不鼓励这样做 see android developers page
使用异步任务执行与网络相关的任务或尝试使用安全线程