我正在尝试通过观看Android app development weather app中的示例在Android中制作应用。现在我有这个致命的异常,我不知道为什么会这样,因为我第一次使用JSON和api。我的错误日志如下:
01-27 03:01:40.622: E/AndroidRuntime(514): FATAL EXCEPTION: AsyncTask #1
01-27 03:01:40.622: E/AndroidRuntime(514): java.lang.RuntimeException: An error occured while executing doInBackground()
01-27 03:01:40.622: E/AndroidRuntime(514): at android.os.AsyncTask$3.done(AsyncTask.java:200)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.lang.Thread.run(Thread.java:1019)
01-27 03:01:40.622: E/AndroidRuntime(514): Caused by: java.lang.NullPointerException
01-27 03:01:40.622: E/AndroidRuntime(514): at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:112)
01-27 03:01:40.622: E/AndroidRuntime(514): at org.json.JSONTokener.nextValue(JSONTokener.java:90)
01-27 03:01:40.622: E/AndroidRuntime(514): at org.json.JSONObject.<init>(JSONObject.java:154)
01-27 03:01:40.622: E/AndroidRuntime(514): at org.json.JSONObject.<init>(JSONObject.java:171)
01-27 03:01:40.622: E/AndroidRuntime(514): at com.example.secondtime.JSONWeatherParser.getWeather(JSONWeatherParser.java:24)
01-27 03:01:40.622: E/AndroidRuntime(514): at com.example.secondtime.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:96)
01-27 03:01:40.622: E/AndroidRuntime(514): at com.example.secondtime.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:1)
01-27 03:01:40.622: E/AndroidRuntime(514): at android.os.AsyncTask$2.call(AsyncTask.java:185)
01-27 03:01:40.622: E/AndroidRuntime(514): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
01-27 03:01:40.622: E/AndroidRuntime(514): ... 4 more
这是我的主要活动类:
package com.example.secondtime;
import com.survivingwithandroid.weatherapp.R;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.secondtime.DailyForecastPageAdapter;
import com.example.secondtime.Location;
import com.example.secondtime.Weather;
import com.example.secondtime.WeatherForecast;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
private TextView cityText;
private TextView condDescr;
private TextView temp;
private TextView press;
private TextView windSpeed;
private TextView windDeg;
private TextView unitTemp;
private TextView hum;
private ImageView imgView;
private static String forecastDaysNum = "3";
private ViewPager pager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String city = "London, UK";
String lang = "en";
cityText = (TextView) findViewById(R.id.cityText);
temp = (TextView) findViewById(R.id.temp);
unitTemp = (TextView) findViewById(R.id.unittemp);
unitTemp.setText("°C");
condDescr = (TextView) findViewById(R.id.skydesc);
pager = (ViewPager) findViewById(R.id.pager);
imgView = (ImageView) findViewById(R.id.condIcon);
JSONWeatherTask task = new JSONWeatherTask();
task.execute(new String[]{city,lang});
JSONForecastWeatherTask task1 = new JSONForecastWeatherTask();
task1.execute(new String[]{city,lang, forecastDaysNum});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class JSONWeatherTask extends AsyncTask<String, Void, Weather> {
@Override
protected Weather doInBackground(String... params) {
Weather weather = new Weather();
String data = ( (new WeatherHttpClient()).getWeatherData(params[0], params[1]));
try {
weather = JSONWeatherParser.getWeather(data);
System.out.println("Weather ["+weather+"]");
weather.iconData = ( (new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));
} catch (JSONException e) {
e.printStackTrace();
}
return weather;
}
@Override
protected void onPostExecute(Weather weather) {
super.onPostExecute(weather);
if (weather.iconData != null && weather.iconData.length > 0) {
Bitmap img = BitmapFactory.decodeByteArray(weather.iconData, 0, weather.iconData.length);
imgView.setImageBitmap(img);
}
cityText.setText(weather.location.getCity() + "," + weather.location.getCountry());
temp.setText("" + Math.round((weather.temperature.getTemp() - 275.15)));
condDescr.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");
}
}
private class JSONForecastWeatherTask extends AsyncTask<String, Void, WeatherForecast> {
@Override
protected WeatherForecast doInBackground(String... params) {
String data = ( (new WeatherHttpClient()).getForecastWeatherData(params[0], params[1], params[2]));
WeatherForecast forecast = new WeatherForecast();
try {
forecast = JSONWeatherParser.getForecastWeather(data);
System.out.println("Weather ["+forecast+"]");
} catch (JSONException e) {
e.printStackTrace();
}
return forecast;
}
@Override
protected void onPostExecute(WeatherForecast forecastWeather) {
super.onPostExecute(forecastWeather);
DailyForecastPageAdapter adapter = new DailyForecastPageAdapter(Integer.parseInt(forecastDaysNum), getSupportFragmentManager(), forecastWeather);
pager.setAdapter(adapter);
}
}
}
还有一个,这是我的主要活动xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="290dp"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/cityText"
style="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true">
</TextView>
<TextView
android:id="@+id/temp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/cityText"
android:layout_centerHorizontal="true">
</TextView>
<TextView
android:id="@+id/unittemp"
android:layout_width="wrap_content"
style="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_below="@id/cityText"
android:layout_toRightOf="@id/temp"
android:layout_alignBaseline="@id/temp">
</TextView>
<TextView
android:id="@+id/skydesc"
android:layout_width="wrap_content"
style="?android:attr/textAppearanceMedium"
android:layout_height="wrap_content"
android:layout_below="@id/temp"
android:layout_alignStart="@id/temp"
android:layout_toRightOf="@id/temp">
</TextView>
<!-- Image weather condition -->
<ImageView android:id="@+id/condIcon"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignTop="@id/temp"
android:layout_toRightOf="@id/temp"/>
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="6" >
<android.support.v4.view.PagerTitleStrip
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#E6E6E6"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
</LinearLayout>
任何对此的帮助都会很棒。提前致谢,抱歉我的英语和语法不好。
答案 0 :(得分:4)
你应该检查返回的data
是否为空。尝试添加一个断点,你会看到..
if(data != null){
//do the parsing stuff
}else{
//something wrong happened during the download..
}
根据stacktrace,你在这里有一个NullPointerException:
JSONWeatherParser.getWeather(data)
当你查看方法的代码时
public String getWeatherData(String location, String lang) {
HttpURLConnection con = null ;
InputStream is = null;
try {
String url = BASE_URL + location;
if (lang != null)
url = url + "&lang=" + lang;
con = (HttpURLConnection) ( new URL(url)).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();
// Let's read the response
StringBuffer buffer = new StringBuffer();
is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ( (line = br.readLine()) != null )
buffer.append(line + "\r\n");
is.close();
con.disconnect();
return buffer.toString();
}
catch(Throwable t) {
t.printStackTrace();
}
finally {
try { is.close(); } catch(Throwable t) {}
try { con.disconnect(); } catch(Throwable t) {}
}
return null;
}
你可以看到它在最后一行返回null。当下载过程中出现错误时会发生这种情况。因此,您肯定需要检查nullpointer,以使代码失败保存。