Java 使用OpenWeatherMap的Android应用程序在用户输入无效城市时崩溃,如何处理API中的404代码?
我的应用程序已经实现了天气,它正在使用OpenWeatherMap中的数据 用户可以通过警报对话框代码输入他们想要的天气城市,但当用户输入无效城市时,应用程序崩溃 从而将URL更改为: {此处城市无效}&units=metric&APPID={APP ID Here} API返回{“cod”:“404”,“message”:“city not found”},这会导致我的应用程序崩溃 我的问题是:如何处理404代码,这样应用程序不会崩溃,但会通知用户他们需要输入有效的城市。-如果这对你们来说是浪费时间,我很抱歉,但我仍在学习,而且对所有这些都很陌生。。。 更详细的解释和非屈尊指导将非常感谢,并将帮助我学习 警报对话框如下所示:Java 使用OpenWeatherMap的Android应用程序在用户输入无效城市时崩溃,如何处理API中的404代码?,java,android,json,api,nullpointerexception,Java,Android,Json,Api,Nullpointerexception,我的应用程序已经实现了天气,它正在使用OpenWeatherMap中的数据 用户可以通过警报对话框代码输入他们想要的天气城市,但当用户输入无效城市时,应用程序崩溃 从而将URL更改为: {此处城市无效}&units=metric&APPID={APP ID Here} API返回{“cod”:“404”,“message”:“city not found”},这会导致我的应用程序崩溃 我的问题是:如何处理404代码,这样应用程序不会崩溃,但会通知用户他们需要输入有效的城市。-如果这对你们来说是浪
private void showChangeCityDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(R.string.change_city_title);
final EditText cityInput = new EditText(MainActivity.this);
cityInput.setInputType(InputType.TYPE_CLASS_TEXT);
cityInput.setHint("Sofia,BG");
builder.setView(cityInput);
builder.setPositiveButton(R.string.submit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (cityInput.getText().toString().equals("")) {
Toast.makeText(MainActivity.this, "Please type a City name!", Toast.LENGTH_LONG).show();
return;
}
CityPreference cityPreference = new CityPreference(MainActivity.this);
cityPreference.setCity(cityInput.getText().toString());
String newCity = cityPreference.getCity();
renderWeatherData(newCity);
}
});
builder.show();
}
这是renderWeatherData的代码:
public void renderWeatherData(String city) {
WeatherTask weatherTask = new WeatherTask();
weatherTask.execute(new String[]{city + "&units=metric"});
}
崩溃时的错误是:
07-25 19:03:28.507 24691-25279/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.vladimirtumbev.android.footballscorekeeper, PID: 24691
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
at org.json.JSONTokener.nextValue(JSONTokener.java:94)
at org.json.JSONObject.<init>(JSONObject.java:156)
at org.json.JSONObject.<init>(JSONObject.java:173)
at data.JSONWeatherParser.getWeather(JSONWeatherParser.java:24)
at com.vladimirtumbev.android.footballscorekeeper.MainActivity$WeatherTask.doInBackground(MainActivity.java:465)
at com.vladimirtumbev.android.footballscorekeeper.MainActivity$WeatherTask.doInBackground(MainActivity.java:458)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
我的JSON天气分析器类:
public class JSONWeatherParser {
public static Weather getWeather(String data){
Weather weather = new Weather();
//Create JSON object from data
try {
JSONObject jsonObject = new JSONObject(data);
Place place = new Place();
JSONObject coordObj = Utils.getObject("coord", jsonObject);
place.setLat(Utils.getFloat("lat", coordObj));
place.setLon(Utils.getFloat("lon", coordObj));
//get Sys object
JSONObject sysObj = Utils.getObject("sys", jsonObject);
place.setCountry(Utils.getString("country",sysObj));
place.setCity(Utils.getString("name",jsonObject));
weather.place = place;
//get Weather info
JSONArray jsonArray = jsonObject.getJSONArray("weather");
JSONObject jsonWeather = jsonArray.getJSONObject(0);
weather.currentCondition.setWeatherId(Utils.getInt("id", jsonWeather));
weather.currentCondition.setDescription(Utils.getString("description", jsonWeather));
weather.currentCondition.setCondition(Utils.getString("main", jsonWeather));
weather.currentCondition.setIcon(Utils.getString("icon", jsonWeather));
JSONObject mainObj = Utils.getObject("main", jsonObject);
weather.currentCondition.setTemperature(Utils.getDouble("temp", mainObj));
JSONObject cloudObj = Utils.getObject("clouds", jsonObject);
weather.clouds.setPrecipitation(Utils.getInt("all", cloudObj));
return weather;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
我还有一些带有setter和getter的模型类,如果需要可以添加它们
谢谢你的帮助 这是堆栈跟踪中非常重要的一行
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
您已经有了NullPointerException(NPE)。您试图获取的字符串长度为null,这会导致它崩溃。堆栈跟踪中有一个行号,指向调用发生的位置。所以找到那条线并用
try {
//line that throws exception
} catch (ExceptionType name) {
//do something in a case of exception
}
在WeatherHTTPClient类中,类似于
if(connection.getResponseCode() == 200) // 200 is ok
{
为ResponseCode 404添加一个条件并相应地处理它。您不能解析任何内容,因此必须显式处理该情况
public class JSONWeatherParser {
public static Weather getWeather(String data){
if (data == null) return null; // return back null
Weather weather = new Weather();
在您无法解析响应的情况下,您可以在UI中弹出一些消息
顺便说一句,HttpGet和HTTPClient都不推荐使用,所以我建议您至少研究一下Volley或改装+Gson
也可以使用Glide或Picasso加载图像响应代码404并相应地进行处理。-我需要“相应地处理”部分的帮助:)显示一个对话框,其中包含您作为响应的一部分收到的消息。我将在哪里添加此内容?你能给我更多的信息吗?我编辑了答案,404不是导致你的应用崩溃的原因。如果您正在使用任何IDE,只需单击堆栈跟踪中的行号,它就会将您带到错误的位置。我不必用try-and-catch来包装它,我只需在主要活动asynctasks中使用“If-else”,但您最近的评论为我指明了正确的方向,因此,我给你投票和正确的答案!:)虽然我能理解为什么它被标记为重复,但由于缺乏一般知识,我不得不针对我的案例专门提出这个问题,因为我无法成功地使用其他问题中的类比。这三个答案都没有完全回答我的问题,但我会给阿尔·皮梅诺夫“正确的答案”,因为它在正确的方向上直接指出了我,并在他的答案下发表了评论,我设法解决了这个问题!非常感谢。你的回答帮助很大!我将研究毕加索和截击:)谢谢!
if(connection.getResponseCode() == 200) // 200 is ok
{
public class JSONWeatherParser {
public static Weather getWeather(String data){
if (data == null) return null; // return back null
Weather weather = new Weather();