-2

I use google places api to return a list of interesting places nearby. Each place and its attributes are enclosed in result and /result tag. After encountering the first /result tag I get Network on main thread exception whenever there is parser.next() statement.

      try {
        int type = parser.getEventType();
         Locations obj = null;

        while (type != XmlPullParser.END_DOCUMENT) {

            String name = parser.getName();
            switch (type) {
                case XmlPullParser.START_TAG: {
                    if (name.equalsIgnoreCase("result"))
                    {obj = new Locations();}

                    else if (name.equalsIgnoreCase("name"))
                        obj.name = parser.nextText();

                    else if (name.equalsIgnoreCase("vicinity"))
                        obj.address = parser.nextText();
                    else if (name.equalsIgnoreCase("lat"))
                        lat = parser.nextText();
                    else if (name.equalsIgnoreCase("lng")) {
                        lng = parser.nextText();
                    LatLng latLng = new LatLng(Double.parseDouble(lat),Double.parseDouble(lng));
                        obj.latlng = latLng;
                    }
                    break;
                }

                case XmlPullParser.END_TAG: {
                    if (name.equalsIgnoreCase("result")) {
                        entries.add(obj);
                    }
                    break;
                }
            }//End Switch Case
            type = parser.next();

            }//End While Block



        } //End try block

      catch (IOException ioex)
      {
        ioex.printStackTrace();
      }
      catch (XmlPullParserException ioex)
      {
        ioex.printStackTrace();
      }
      catch (Exception ioex)
      {
        ioex.printStackTrace();
      }

Each object of Locations class represent a place. I have used a separate thread to perform httpurl connection activities and have also set read timeout to 3 mins. (below class is used to open http network connection)

    public class DownloadxmlTask  {

    public String status=null;
    public InputStream isi=null;
    private InputStream loadXmlfromnetwork(String url) {
    InputStream in = null;
    try {
        URL urlobj = new URL(url);
        HttpURLConnection conobj = (HttpURLConnection) urlobj.openConnection();
        conobj.setReadTimeout(3*60000);
        in = conobj.getInputStream();
        isi=in;
        status = in.toString();
        wait(3*60000);
        conobj.disconnect();
     } catch (Exception ex) {
        status =ex.getLocalizedMessage().toString();
      }
      return in;
      }
     protected InputStream doInBackground(String params) {

        final String url = params;

    Thread newthread=new Thread() {
        @Override
        public void run() {
            loadXmlfromnetwork(url);
        }
            };
        newthread.start();
      return isi;
      }
     } 
  • what does `Locations` do? – tyczj Aug 05 '15 at 14:05
  • I don't get this error if I use a different xml request. – Bharaneedharan Aug 05 '15 at 14:08
  • @tyczj. I could see clearly that the Locations class may be a POJO class. Please look into the question and encourage forum newbie. – Nilanchala Aug 05 '15 at 14:08
  • @Nilanchala he said he was getting the error on the first tag, how do you know that `Locations` does not do some network operation in the constructor? – tyczj Aug 05 '15 at 14:11
  • @Bharaneedharan if you say you use a different thread to make the network connection you should show that because nothing in your question shows you are doing that – tyczj Aug 05 '15 at 14:21
  • @tyczj I have added the whole class. – Bharaneedharan Aug 05 '15 at 14:29
  • @Bharaneedharan there are many problems with your `DownloadTaskXml` class your `doInBackground` method is going to return before your thread is executed. move your code to use an `AsyncTask` like was suggested and then return your inputstream to your `onPostExecute` of your asynctask – tyczj Aug 05 '15 at 14:34

1 Answers1

0

The error is self explanatory. You need to perform your parser call inside a separate thread off from UI main thread. While there are various technique to achieve this, the simplest one is to create a AsyncTask.

I have pasted the simplest version of AsyncTask implementation. The doInBackground() method runs on its own separate thread and onPostExecute() executes on UI main thread.

Place all your parser logic inside doInBackground() method.

private final AsyncTask<Void, Void, Void> cacheInitializationTask = new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            //Runs on UI thread
            super.onPostExecute(aVoid);
        }
    };

For more information visit this link AsyncTask

Nilanchala
  • 5,891
  • 8
  • 42
  • 72