执行代码时出现IOMainThreadException

时间:2013-02-07 16:00:39

标签: android

执行以下代码时,会抛出错误:

  

IOMainThreadException

有人可以找出错误发生的位置吗?

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

2 个答案:

答案 0 :(得分:1)

您的方法QueryYahooWeather()打开网络连接。 Android会在API等级NetworkOnMainThreadException(Android 3.0)及更高版本上投放11。顾名思义,您不能在主(UI)线程上打开网络连接。

原因是“Designing for Responsiveness”。如果服务器不可用或用户处于弱连接状态,则您的应用程序会滞后,因为它正在等待服务器响应。

在自己的线程中运行您的网络代码以解决问题。

更新:ASyncTask是一种正确的方法。 (参见上面的Geobits建议)

答案 1 :(得分:0)

异常是因为您正在访问network并对main UI thread执行其他繁重的操作,并且android不允许这样做。 您需要实施AsyncTask以在background

中执行这些繁重的操作

Refer to my answer on using AsyncTaskhere