我试图在android studio中构建一个非常基本的天气应用程序。我正在使用AsyncClass返回多个字符串。
正如您在代码中看到的,我使用了一个名为" Wrapper"的类。用于存储我的字符串,所以我可以返回一个类对象,并在AsyncTask的onPostExecute方法中使用它。我面临的问题是,当我测试应用程序时,所有返回的Stringsshow都是未定义的(Wrapper类的默认值)。这意味着字符串没有在doInBackground方法中更新,我似乎无法找出原因!
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(MainActivity.class.getSimpleName(), "Can't connect to Google Play Services!");
}
private class Wrapper
{
String Temperature = "UNDEFINED";
String city = "UNDEFINED";
String country = "UNDEFINED";
}
private class GetWeatherTask extends AsyncTask<String, Void, Wrapper> {
private TextView textView;
public GetWeatherTask(TextView textView) {
this.textView = textView;
}
@Override
protected Wrapper doInBackground(String... strings) {
Wrapper w = new Wrapper();
String Temperature = "x";
String city = "y";
String country = "z";
try {
URL url = new URL(strings[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
JSONObject topLevel = new JSONObject(builder.toString());
JSONObject main = topLevel.getJSONObject("main");
JSONObject cityobj = topLevel.getJSONObject("city");
Temperature = String.valueOf(main.getDouble("temp"));
city = cityobj.getString("name");
country = cityobj.getString("country");
w.Temperature= Temperature;
w.city= city;
w.country=country;
urlConnection.disconnect();
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return w;
}
@Override
protected void onPostExecute(Wrapper w) {
textView.setText("Current Temperature: " + w.Temperature + " C" + (char) 0x00B0
+"\n" + "Current Location: "+ w.country +"\n" + "City: "+ w.city );
}
}
}
更新
原来我在我的代码中使用了错误的网址,我正在使用: http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=%s&appid=%s
相反,我应该一直在使用:
http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&units=%s&appid=%s
-aka而不是天气我应该使用预测
答案 0 :(得分:1)
在研究了你的代码之后,你的try块失败了,它正在返回你的对象,但是空了,或者你的JSON解析有问题。如果你能向我们展示你试图解析的JSON,那将是一个很大的帮助。
话虽如此,它仍然显示为“UNDEFINED”的事实是因为这是你初始化它的方式,并且因为(JSON解析可能失败),对象将以未编辑状态返回。
修改强>
您正在解析JSON错误。您正试图在顶层目录中找到一个名为“main”的对象,但是主对象只存在于名为list的数组中!
请在此处查看更易于查看和直观的表示:http://prntscr.com/dlhlrk
您可以使用此站点来帮助可视化您的JSON并根据它创建适当的解决方案。 https://jsonformatter.curiousconcept.com/
答案 1 :(得分:1)
查看之前发布的API(api.openweathermap.org),您正在尝试访问不存在的变量。我建议你看看API returns是什么,如果你得到一个JSONException,我会逐个尝试获取变量
编辑: 你在用什么API?在您的帖子中,您说它是http://api.openweathermap.org/data/2.5/weather,但在上面的评论中,您说它是http://api.openweathermap.org/data/2.5/forecast。
如果您使用的是天气API(如最初所述),您可以使用以下内容:
@Override
protected Wrapper doInBackground(String... strings) {
Wrapper w = new Wrapper();
try {
URL url = new URL(strings[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
Log.d("JSON", builder.toString());
JSONObject topLevel = new JSONObject(builder.toString());
JSONObject main = topLevel.getJSONObject("main");
JSONObject sys = topLevel.getJSONObject("sys");
w.Temperature = String.valueOf(main.getDouble("temp"));
w.city = topLevel.getString("name");
w.country = sys.getString("country");
urlConnection.disconnect();
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return w;
}
答案 2 :(得分:1)
您的错误从此处开始
JSONObject main = topLevel.getJSONObject("main");
可能是因为topLevel
对象没有"main"
键。
{
"city":{ },
"cod":"200",
"message":0.1859,
"cnt":40,
"list":[ ]
}
将你的JSON扔到这里。 https://jsonformatter.curiousconcept.com/
您会注意到"main"
元素中有许多"list"
个密钥,但您必须解析从getJSONArray("list")
开始的密钥。
基本上,就像这样
String city = "undefined";
String country = "undefined";
List<Double> temperatures = new ArrayList<Double>();
try {
JSONObject object = new JSONObject(builder.toString());
JSONObject jCity = object.getJSONObject("city");
city = jCity.getString("name");
country = jCity.getString("country");
JSONArray weatherList = object.getJSONArray("list");
for (int i = 0; i < weatherList.length(); i++) {
JSONObject listObject = weatherList.getJSONObject(i);
double temp = listObject.getJSONObject("main").getDouble("temp");
temperatures.add(temp);
}
} catch (JSONException e) {
e.printStackTrace();
}
return new Wrapper(city, country, temperatures);