我试图从yahoo weather api中获取一些数据,但它在doBackGround()中显示了一个致命异常。第一次它会正常运行,但第二次运行,它显示我这个错误。我尝试使用此代码并在此方法中显示错误
String url1 = src.substring(1, src.length() - 2);
使用代码是:
package com.gird.completeontologyproject;
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 java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
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.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class WeatherSHow extends Activity {
ImageView icon1 = null;
TextView date = null, temp = null, condition = null, humidity = null,
wind = null;
ProgressDialog dialog;
String temperature = null, date1 = null, condition1 = null,
humidity1 = null, wind1 = null, link = null;
ArrayList<String> weather=null;
Bitmap icon = null;
protected void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.weather_pref);
icon1 = (ImageView) findViewById(R.id.icon);
date = (TextView) findViewById(R.id.dateText);
temp = (TextView) findViewById(R.id.tempText);
condition = (TextView) findViewById(R.id.conditionText);
humidity = (TextView) findViewById(R.id.humidityText);
wind = (TextView) findViewById(R.id.windText);
new RetriveWeatherTask().execute();
}
class RetriveWeatherTask extends AsyncTask<Void, String, String> {
protected void onPreExecute() {
dialog = new ProgressDialog(WeatherSHow.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage("Loading...");
dialog.setCancelable(false);
dialog.show();
}
@Override
protected String doInBackground(Void... params) {
String Result = "";
String uri = "http://weather.yahooapis.com/forecastrss?w=2295415&u=c;";
HttpClient httpclient = new DefaultHttpClient();
HttpContext localcontext = new BasicHttpContext();
HttpGet httpget = new HttpGet(uri);
try {
HttpResponse httpresponse = httpclient.execute(httpget,
localcontext);
HttpEntity entity = httpresponse.getEntity();
if (entity != null) {
InputStream inputstream = entity.getContent();
Reader resder = new InputStreamReader(inputstream);
BufferedReader bufferReader = new BufferedReader(resder);
StringBuilder stringBuilder = new StringBuilder();
String ReadLine = null;
while ((ReadLine = bufferReader.readLine()) != null) {
stringBuilder.append(ReadLine + "\n");
}
Result = stringBuilder.toString();
}
} catch (ClientProtocolException e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
}
Document docu = null;
DocumentBuilder parse1 = null;
DocumentBuilderFactory docuFactory = DocumentBuilderFactory
.newInstance();
try {
parse1 = docuFactory.newDocumentBuilder();
docu = parse1
.parse(new ByteArrayInputStream(Result.getBytes()));
} catch (ParserConfigurationException ed) {
Toast.makeText(getApplicationContext(), ed.toString(),
Toast.LENGTH_LONG).show();
} catch (SAXException e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
}
Node tempretureNode = docu.getElementsByTagName(
"yweather:condition").item(0);
temperature = tempretureNode.getAttributes().getNamedItem("temp")
.getNodeValue().toString();
Node TempratureUnit = docu.getElementsByTagName("yweather:units")
.item(0);
temperature = temperature
+ " "
+ TempratureUnit.getAttributes()
.getNamedItem("temperature").getNodeValue()
.toString();
Node dateNode = docu.getElementsByTagName("yweather:forecast")
.item(0);
date1 = dateNode.getAttributes().getNamedItem("date")
.getNodeValue().toString();
Node conditionNode = docu
.getElementsByTagName("yweather:condition").item(0);
condition1 = conditionNode.getAttributes().getNamedItem("text")
.getNodeValue().toString();
Node humidityNode = docu
.getElementsByTagName("yweather:atmosphere").item(0);
humidity1 = humidityNode.getAttributes().getNamedItem("humidity")
.getNodeValue().toString();
Node windNode = docu.getElementsByTagName("yweather:wind").item(0);
wind1 = windNode.getAttributes().getNamedItem("speed")
.getNodeValue().toString();
Node windUnits = docu.getElementsByTagName("yweather:units")
.item(0);
wind1 = wind1
+ " "
+ windUnits.getAttributes().getNamedItem("speed")
.getNodeValue().toString();
String desc = docu.getElementsByTagName("item").item(0)
.getChildNodes().item(13).getTextContent().toString();
StringTokenizer str = new StringTokenizer(desc, "<=>");
String src = str.nextToken();
//Exception In this Method.
String url1 = src.substring(1, src.length() - 2);
Pattern TAG_REGEX = Pattern.compile("(.+?)<br />");
Matcher matcher = TAG_REGEX.matcher(desc);
weather=new ArrayList<String>();
while (matcher.find()) {
weather.add(matcher.group(1));
}
Pattern links = Pattern.compile("(.+?)<BR/>");
matcher = links.matcher(desc);
while (matcher.find()) {
link = matcher.group(1);
}
InputStream in = null;
try {
// in = OpenHttpConnection(url1);
int response = -1;
URL url = new URL(url1);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
icon = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return Result;
}
protected void onPostExecute(String result) {
System.out.println("POST EXECUTE");
if (dialog.isShowing())
dialog.dismiss();
temp.setText("Temperature: " + temperature);
condition.setText("Condition: " + condition1);
date.setText("Date: " + date1);
humidity.setText("Humidity: " + humidity1);
wind.setText("Wind: " + wind1);
icon1.setImageBitmap(icon);
}
}
}
我如何解决此错误: 错误日志:
06-05 19:32:11.876: E/Trace(4418): error opening trace file: No such file or directory (2)
06-05 19:32:17.584: E/AndroidRuntime(4418): FATAL EXCEPTION: AsyncTask #1
06-05 19:32:17.584: E/AndroidRuntime(4418): java.lang.RuntimeException: An error occured while executing doInBackground()
06-05 19:32:17.584: E/AndroidRuntime(4418): at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-05 19:32:17.584: E/AndroidRuntime(4418): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.lang.Thread.run(Thread.java:856)
06-05 19:32:17.584: E/AndroidRuntime(4418): Caused by: java.lang.StringIndexOutOfBoundsException: length=1; regionStart=1; regionLength=-2
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.lang.String.startEndAndLength(String.java:593)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.lang.String.substring(String.java:1474)
06-05 19:32:17.584: E/AndroidRuntime(4418): at com.gird.completeontologyproject.WeatherSHow$RetriveWeatherTask.doInBackground(WeatherSHow.java:169)
06-05 19:32:17.584: E/AndroidRuntime(4418): at com.gird.completeontologyproject.WeatherSHow$RetriveWeatherTask.doInBackground(WeatherSHow.java:1)
06-05 19:32:17.584: E/AndroidRuntime(4418): at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-05 19:32:17.584: E/AndroidRuntime(4418): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
答案 0 :(得分:0)
您的src.length()
返回1。
在致电String.substring()
答案 1 :(得分:0)
src的长度是多少?它太短了,这就是错误的原因。
您应该检查该行之前的长度,如下所示:
String url1 = "";
if(src.lenth() > 4)
url1 = src.substring(1, src.length() - 2);
else
return "";
4是因为你从第二个字符(索引1)开始,并在src长度之前的第二个字符串完成(最小4-2 = 2)。你可以把其他if语句,如果你知道子串应该是什么样子以及应该多长时间。
你不需要其他,因为url1已经设置为“”但你可以根据你的代码放一些Toast或其他东西。
答案 2 :(得分:0)
你在WeatherSHow.java:169
得到 StringIndexOutOfBoundsException ..所以@Zoran建议请检查长度
String url1 = "";
if(src.lenth() > 4)
url1 = src.substring(1, src.length() - 2);
,您正试图在Toast
中显示太多doInBackground()
条消息,这些消息正在创建问题。您无法更新doInBackground()
中的用户界面..在你的onPostExecute()..
您可以将Toast
打包在runOnUIThread()
中,但这不是最佳解决方案。
发生错误时应在catch块中设置一个布尔标志,然后在Toast
,onProgressUpdate()
或任何其他具有UI访问权限的方法中显示适当的onPostExecute()
。真。
选中此link以了解有关异步任务的更多信息..
答案 3 :(得分:0)
这是你的代码:
String url1 = src.substring(1, src.length() - 2);
此代码存在以下问题:Caused by: java.lang.StringIndexOutOfBoundsException: length=1; regionStart=1; regionLength=-2
。 src
只有1个字符,因此当您致电src.length() - 2
时返回-1。
我的解决方案是,您必须在调用String
方法之前检查substring
的长度。
类似的东西:
int length = src.length();
int start = 1;
int end = length - 2;
String url1 = "";
if(length > start && length < end){
url1 = src.substring(1, src.length() - 2);
}
希望有所帮助!