0

When I execute the following code, it throws an error:

IOMainThreadException

Could anyone please find out where the error occurs ?

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.Reader;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.xml.sax.SAXException;

import android.app.Activity;

import android.os.Bundle;

import android.widget.ImageView;

import android.widget.TextView;

import android.widget.Toast;

public class AndroidYahooWeatherDOMActivity extends Activity {

    TextView weather;
    TextView txtcity;
    TextView txtregion;
    TextView txtcountry;
    TextView txttemp;
    TextView txtpressure;
    TextView txthumidity;
    TextView txtspeed;
    TextView txtsunrise;
    TextView txtsunset;
    TextView txtcondition;

    TextView day1;
    TextView date1;
    TextView low1;
    TextView high1;
    TextView text1;
    TextView day2;
    TextView date2;
    TextView low2;
    TextView high2;
    TextView text2;

    ImageView img;
    ImageView nxtday1;
    ImageView nxtday2;


    class MyWeather {
        WeatherImageHandler im = new WeatherImageHandler(getApplicationContext());
        WeatherImageHandler im1 = new WeatherImageHandler(getApplicationContext());
        WeatherImageHandler im2 = new WeatherImageHandler(getApplicationContext());
        String description;
        String city;
        String region;
        String country;

        String windChill;
        String windDirection;
        String windSpeed;

        String sunrise;
        String sunset;

        String conditiontext;
        String conditiondate;

        String temp;
        String pressure;
        String humidity;
        String visibility;
        String code;

        String rising;

        String day;
        String date;
        String low;
        String high;
        String text;
        String code0;

        String day1;
        String date1;
        String low1;
        String high1;
        String text1;
        String code1;

        String day2;
        String date2;
        String low2;
        String high2;
        String text2;
        String code2;


        public String toString() {

            return "\n- " + description + " -\n\n" + "city: " + city + "\n"
                    + "region: " + region + "\n" + "country: " + country
                    + "\n\n"

                    + "Wind\n" + "chill: " + windChill + "\n" + "direction: "
                    + windDirection + "\n" + "speed: " + windSpeed + "\n\n"

                    + "Sunrise: " + sunrise + "\n" + "Sunset: " + sunset
                    + "\n\n"

                    + "Condition: " + conditiontext + "\n" + conditiondate
                    + "\n\n" + "temp:" + temp + "\n" + "pressure:" + pressure
                    + "\n" + "humidity" + humidity + "\n" + "rising" + rising
                    + "\n" + "visibility" + visibility + "\n"+"code  :" +code+"\n\n"

                    + "day  :" + day
                    + "\n" + "date  :" + date + "\n" + "low  :" + low + "\n" + "high  :"
                    + high+ "\n" + "text  :" + text+"\n"+"code"+code0+"\n\n"

                    + "day  :" + day1
                    + "\n" + "date  :" + date1 + "\n" + "low  :" + low1 + "\n" + "high  :"
                    + high1+ "\n" + "text  :" + text1+"code"+code1+"\n\n"

                    + "day  :" + day2
                    + "\n" + "date  :" + date2 + "\n" + "low  :" + low2 + "\n" + "high  :"
                    + high2+ "\n" + "text  :" + text2+"code"+code2;


        }
    }

        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        txtcity = (TextView) findViewById(R.id.city);
        txtregion = (TextView) findViewById(R.id.region);
        txtcountry = (TextView) findViewById(R.id.country);
        txttemp = (TextView) findViewById(R.id.temp);
        txtpressure = (TextView) findViewById(R.id.pressure);
        txthumidity = (TextView) findViewById(R.id.humidity);
        txtspeed = (TextView) findViewById(R.id.speed);
        txtsunrise = (TextView) findViewById(R.id.sunrise);
        txtsunset = (TextView) findViewById(R.id.sunset);
        txtcondition = (TextView) findViewById(R.id.condition);

        day1 = (TextView) findViewById(R.id.day1);
        date1 = (TextView) findViewById(R.id.date1);
        low1 = (TextView) findViewById(R.id.low1);
        high1 = (TextView) findViewById(R.id.high1);
        text1 = (TextView) findViewById(R.id.text1);

        day2 = (TextView) findViewById(R.id.day2);
        date2 = (TextView) findViewById(R.id.date2);
        low2 = (TextView) findViewById(R.id.low2);
        high2 = (TextView) findViewById(R.id.high2);
        text2 = (TextView) findViewById(R.id.text2);


        img = (ImageView) findViewById(R.id.imageView1);
        nxtday1 = (ImageView) findViewById(R.id.nextday1);
        nxtday2 = (ImageView) findViewById(R.id.nextday2);

        String weatherString = QueryYahooWeather();
        Document weatherDoc = convertStringToDocument(weatherString);

        MyWeather weatherResult = parseWeather(weatherDoc);
        txtcity.setText(weatherResult.city);
        txtregion.setText(weatherResult.region);
        txtcountry.setText(weatherResult.country);
        txttemp.setText(weatherResult.temp);
        txtpressure.setText(weatherResult.pressure);
        txthumidity.setText(weatherResult.humidity);
        txtspeed.setText(weatherResult.windSpeed);
        txtsunrise.setText(weatherResult.sunrise);
        txtsunset.setText(weatherResult.sunset);
        txtcondition.setText(weatherResult.date);

        day1.setText(weatherResult.day);
        date1.setText(weatherResult.date);
        low1.setText(weatherResult.low);
        high1.setText(weatherResult.high);
        text1.setText(weatherResult.text);

        day2.setText(weatherResult.day1);
        date2.setText(weatherResult.date1);
        low2.setText(weatherResult.low1);
        high2.setText(weatherResult.high1);
        text2.setText(weatherResult.text1);

        img.setImageDrawable(weatherResult.im.getWeatherImage());
        nxtday1.setImageDrawable(weatherResult.im1.getWeatherImage());
        nxtday2.setImageDrawable(weatherResult.im2.getWeatherImage());
    }

    private MyWeather parseWeather(Document srcDoc) {

        MyWeather myWeather = new MyWeather();

        myWeather.description = srcDoc.getElementsByTagName("description")
                .item(0).getTextContent();


        Node locationNode = srcDoc.getElementsByTagName("yweather:location")
                .item(0);
        myWeather.city = locationNode.getAttributes().getNamedItem("city")
                .getNodeValue().toString();
        myWeather.region = locationNode.getAttributes().getNamedItem("region")
                .getNodeValue().toString();
        myWeather.country = locationNode.getAttributes()
                .getNamedItem("country").getNodeValue().toString();


        Node windNode = srcDoc.getElementsByTagName("yweather:wind").item(0);
        myWeather.windChill = windNode.getAttributes().getNamedItem("chill")
                .getNodeValue().toString();
        myWeather.windDirection = windNode.getAttributes()
                .getNamedItem("direction").getNodeValue().toString();
        myWeather.windSpeed = windNode.getAttributes().getNamedItem("speed")
                .getNodeValue().toString();


        Node atmosphereNode = srcDoc
                .getElementsByTagName("yweather:atmosphere").item(0);
        myWeather.humidity = atmosphereNode.getAttributes()
                .getNamedItem("humidity").getNodeValue().toString();
        myWeather.visibility = atmosphereNode.getAttributes()
                .getNamedItem("visibility").getNodeValue().toString();
        myWeather.pressure = atmosphereNode.getAttributes()
                .getNamedItem("pressure").getNodeValue().toString();
        myWeather.rising = atmosphereNode.getAttributes()
                .getNamedItem("rising").getNodeValue().toString();


        Node astronomyNode = srcDoc.getElementsByTagName("yweather:astronomy")
                .item(0);
        myWeather.sunrise = astronomyNode.getAttributes()
                .getNamedItem("sunrise").getNodeValue().toString();
        myWeather.sunset = astronomyNode.getAttributes().getNamedItem("sunset")
                .getNodeValue().toString();


        Node conditionNode = srcDoc.getElementsByTagName("yweather:condition")
                .item(0);
        myWeather.conditiontext = conditionNode.getAttributes()
                .getNamedItem("text").getNodeValue().toString();
        myWeather.conditiondate = conditionNode.getAttributes()
                .getNamedItem("date").getNodeValue().toString();
        myWeather.temp = conditionNode.getAttributes().getNamedItem("temp")
                .getNodeValue().toString();
        myWeather.code = conditionNode.getAttributes().getNamedItem("code")
                .getNodeValue().toString();
        myWeather.im.setWeatherImage(myWeather.code);


        Node forecastNode1 = srcDoc.getElementsByTagName("yweather:forecast")
                .item(0);
        myWeather.day = forecastNode1.getAttributes().getNamedItem("day")
                .getNodeValue().toString();
        myWeather.date = forecastNode1.getAttributes().getNamedItem("date")
                .getNodeValue().toString();
        myWeather.low = forecastNode1.getAttributes().getNamedItem("low")
                .getNodeValue().toString();
        myWeather.high = forecastNode1.getAttributes().getNamedItem("high")
                .getNodeValue().toString();
        myWeather.text = forecastNode1.getAttributes().getNamedItem("text")
                .getNodeValue().toString();
        myWeather.code0 = forecastNode1.getAttributes().getNamedItem("code")
                .getNodeValue().toString();
        myWeather.im1.setWeatherImage(myWeather.code0);

        Node forecastNode2 = srcDoc.getElementsByTagName("yweather:forecast")
                .item(1);
        myWeather.day1 = forecastNode2.getAttributes().getNamedItem("day")
                .getNodeValue().toString();
        myWeather.date1 = forecastNode2.getAttributes().getNamedItem("date")
                .getNodeValue().toString();
        myWeather.low1 = forecastNode2.getAttributes().getNamedItem("low")
                .getNodeValue().toString();
        myWeather.high1 = forecastNode2.getAttributes().getNamedItem("high")
                .getNodeValue().toString();
        myWeather.text1 = forecastNode2.getAttributes().getNamedItem("text")
                .getNodeValue().toString();
        myWeather.code1 = forecastNode1.getAttributes().getNamedItem("code")
                .getNodeValue().toString();
        myWeather.im2.setWeatherImage(myWeather.code1);


        return myWeather;
    }

    private Document convertStringToDocument(String src) {
        Document dest = null;

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder parser;

        try {
            parser = dbFactory.newDocumentBuilder();
            dest = parser.parse(new ByteArrayInputStream(src.getBytes()));
        } catch (ParserConfigurationException e1) {
            e1.printStackTrace();
            Toast.makeText(AndroidYahooWeatherDOMActivity.this, e1.toString(),
                    Toast.LENGTH_LONG).show();
        } catch (SAXException e) {
            e.printStackTrace();
            Toast.makeText(AndroidYahooWeatherDOMActivity.this, e.toString(),
                    Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(AndroidYahooWeatherDOMActivity.this, e.toString(),
                    Toast.LENGTH_LONG).show();
        }

        return dest;
    }

    private String QueryYahooWeather() {

        String qResult = "";
        String queryString = "http://weather.yahooapis.com/forecastrss?w=2295422";

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(queryString);

        try {
            HttpEntity httpEntity = httpClient.execute(httpGet).getEntity();

            if (httpEntity != null) {
                InputStream inputStream = httpEntity.getContent();
                Reader in = new InputStreamReader(inputStream);
                BufferedReader bufferedreader = new BufferedReader(in);
                StringBuilder stringBuilder = new StringBuilder();

                String stringReadLine = null;

                while ((stringReadLine = bufferedreader.readLine()) != null) {
                    stringBuilder.append(stringReadLine + "\n");
                }

                qResult = stringBuilder.toString();
            }

        } catch (ClientProtocolException e) {
            e.printStackTrace();
            Toast.makeText(AndroidYahooWeatherDOMActivity.this, e.toString(),
                    Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(AndroidYahooWeatherDOMActivity.this, e.toString(),
                    Toast.LENGTH_LONG).show();
        }

        return qResult;
    }
}
Alfergon
  • 5,463
  • 6
  • 36
  • 56
Ragavi
  • 1
  • Please use the formatting options to format your question (there is a preview below your editting field!). Also post the complete error+stacktrace, it probably has a line-number. – Nanne Feb 07 '13 at 16:03
  • 1
    Which line ? Could you post the log ? – Manitoba Feb 07 '13 at 16:03
  • 1
    Post the logcat and **relevant** code – Raghav Sood Feb 07 '13 at 16:03
  • Most likely related to `NetworkOnMainThreadException`. Move your network calls(like querying Yahoo weather, for instance) and/or heavy I/O to another thread. I'd recommend `ASyncTask` to handle that, it's the Android-y way to do it. Not only will it get rid of the exception, it will also make the UI more smooth and fluid, and prevent it from locking up while awaiting results. – Geobits Feb 07 '13 at 16:23

2 Answers2

1

Your method QueryYahooWeather() opens a network connection. Android will throw a NetworkOnMainThreadException on API Level 11 (Android 3.0) and above. As its name says, you must not open a network connection on the main (UI) thread.

The reason for this is the principle "Designing for Responsiveness". If the server is not available or the user is on a weak connection, your app lags because it's waiting for a server response.

Run your networking code in an own Thread to fix the issue.

Update: ASyncTask is a proper way to do this. (See Geobits suggestion above)

ottel142
  • 2,016
  • 1
  • 26
  • 37
0

The exception is because you are accessing the network and doing other heavy operations on the main UI thread and android does not allows this. You would need to implement AsyncTask to perform these heavy operations in the background

Refer to my answer on using AsyncTaskhere

Community
  • 1
  • 1
Robin Chander
  • 7,225
  • 3
  • 28
  • 42
  • Since I am new to android can u pls tell me in which line i have to add ASnycTask? Or do i need to create ASyncTask in a separate class and integrate in main UI thread? – Ragavi Feb 11 '13 at 15:04
  • You are accessing the network in your `QueryYahooWeather` method. Create a separate class extending AsyncTask. Then take all of your stuff in `QueryYahooWeather` and implement it in doInBackground method of AsyncTask. – Robin Chander Feb 11 '13 at 15:17