android 4.1中的调用web服务
我这里的代码在2.3中一直有效,现在我们必须更新它,我收到了很多错误,比如android 4.1中的调用web服务,android,android-asynctask,Android,Android Asynctask,我这里的代码在2.3中一直有效,现在我们必须更新它,我收到了很多错误,比如NetworkOnMainThreadException。我想从我的web服务中获取一个xml,将其下载并解析为一个数组列表。这是密码 //Gets the xml from the url specified String CallWebService(String url){ String xml = null; try { // defaultHttpClien
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();
编辑
所以我正在尝试异步方式,但仍然不起作用。它根本没有点击getdoElement。这是代码
//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);
}
}
//我在onCreate()中调用它
新建getAppInfo()。执行(“http://webservice.example.com");
私有类getAppInfo扩展了异步任务{
/**系统调用它以在工作线程中执行工作,并
*将给定给AsyncTask.execute()的参数传递给它*/
受保护的字符串doInBackground(字符串…URL){
返回CallWebService(URL[0]);
}
/**系统调用它来执行UI线程中的工作,并提供
*doInBackground()的结果*/
受保护的void onPostExecute(字符串xml){
Document doc=getDomeElement(xml);//获取DOM元素
NodeList nl=doc.getElementsByTagName(“详细信息”);
getChildElements(nl);
}
}
您必须执行异步任务:
顺便说一句,这是需要从安卓3(如果我记得很清楚)
我已经在我的应用程序中实现了这一点,您可以在此处浏览我的代码:希望这有帮助
例如,在activity 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();
当应用程序试图在其主线程上执行网络操作时引发的异常 这仅适用于目标为蜂巢SDK或更高版本的应用程序。针对早期SDK版本的应用程序可以在其主事件循环线程上进行联网,但这是非常不鼓励的
您的网络相关任务是否使用异步任务或尝试使用安全线程因此,我是否将我的三个方法封装在一个扩展异步的方法中,并保持我对它的调用方式不变?是的,完全正确。应该有用。AsyncTask是避免阻塞UI操作所必需的。只需在主类中调用execute方法。实际上,您必须实现一个新类,该类使用他的方法扩展AsyncTask。请检查上述代码。这是我的主要活动。我这样做对吗?调用CallWebServer方法是否正确?在执行该方法之后,它会将结果传递给onPostExecute(),这
t.start()
go在哪里?这是在run方法中吗?start()将在run()中运行已定义线程的代码{}因此决定何时需要启动后台作业您没有显示在何处调用此行String serviceURL=”http://webservice.example.com/";代码>stringxml=CallWebService(serviceURL)代码>所以我不知道应该在哪里运行线程…看起来正确。不知道为什么它可能不起作用。你试过调试吗?尝试将断点放在t.start()
上,并放在run()
Yes中的第一行,它会转到t.start()并跳过它