执行以下代码时,会抛出错误:
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;
}
}
答案 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