简体   繁体   中英

Call web service in android 4.1

I have this code here that worked all this time in 2.3 now we have to update it and I am getting a lot of errors like NetworkOnMainThreadException . I want to go and grab a xml from my web service, bring it down and parse it into an array list. Here is the code

//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 "";
 }

I also have a getChildElements method. The problem is when I call this method. I used to do so like this:

String serviceURL = "http://webservice.example.com/";
String xml = CallWebService(serviceURL);
Document doc = GetDomElement(xml); // getting DOM element

NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl); 

But now in 4.1 I need to do this asynchronously and I don't know how. Any help will be greatly appreciated.

EDIT

Here is what i have bu the Thread does not start

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();

EDIT

So I am trying the async way and it still wont work. Its not hitting the GetDomElement at all. Here is the code.

   //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); 
    }
}

You have to implement an AsyncTask:

http://developer.android.com/reference/android/os/AsyncTask.html

Btw this is needed from Android 3 (if I remember well).

I've implemented this in my app, you can browse my code here: https://github.com/enrichman/roma-tre/blob/master/src/com/roma3/infovideo/utility/rss/RssTask.java

Define a Handler in your main ui thread in activity onCreate for example

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);
    }
 };

Then run all your long jobs in background thread

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();

The exception that is thrown when an application attempts to perform a networking operation on its main thread.

This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged see android developers page

Do your network related task using Async task or try using safe threads

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM