android 4.1中的调用web服务

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

我这里的代码在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();
编辑

所以我正在尝试异步方式,但仍然不起作用。它根本没有点击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()并跳过它