如何使用 Retrofit 从 OpenWeatherMap API 获取"weather"对象数据



我刚开始开发,我正试图为一项任务开发一个android天气应用程序。我在youtube上遵循了本教程创建了它。一切都很好,但我无法从;天气;对象
OpenWeatherMap API

{
"coord": {
"lon": -122.08,
"lat": 37.39
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 282.55,
"feels_like": 281.86,
"temp_min": 280.37,
"temp_max": 284.26,
"pressure": 1023,
"humidity": 100
},
"visibility": 16093,
"wind": {
"speed": 1.5,
"deg": 350
},
"clouds": {
"all": 1
},
"dt": 1560350645,
"sys": {
"type": 1,
"id": 5122,
"message": 0.0139,
"country": "US",
"sunrise": 1560343627,
"sunset": 1560396563
},
"timezone": -25200,
"id": 420006353,
"name": "Mountain View",
"cod": 200
}

ApiClient.java

package com.dhanurjan.weather.Retrofit;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {

private static Retrofit retrofit = null;
public static  Retrofit getClient(){ //creating object
if (retrofit == null){
retrofit = new Retrofit.Builder() //Retrofit.Builder class uses the Builder API to allow defining the URL end point for the HTTP operations and finally build a new Retrofit instance.
//http://api.openweathermap.org/data/2.5/weather?q=London&APPID=76a35a17f3e1bce771a09f3555b614a8
.baseUrl("https://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}

return retrofit;
}
}

ApiInterface.java

package com.dhanurjan.weather.Retrofit;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ApiInterface {

@GET("weather?APPID=76a35a17f3e1bce771a09f3555b614a8&units=metric")
Call<Example> getWeatherData(@Query("q") String name);

}

示例.java

package com.dhanurjan.weather.Retrofit;
import com.google.gson.annotations.SerializedName;
public class Example {
@SerializedName("sys")
private Sys sys;
@SerializedName("coord")
private Coord coord;
@SerializedName("main")
private Main main;
@SerializedName("weather")
private Weather weather;
public Sys getSys() { return sys; }
public void setSys(Sys sys) {
this.sys = sys;
}
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Weather getWeather() { return weather; }
public void setWeather(Weather weather) { this.weather = weather; }
}

Weather.java

package com.dhanurjan.weather.Retrofit;
import com.google.gson.annotations.SerializedName;
public class Weather {
@SerializedName("main")
String main;
@SerializedName("description")
String description;

public String getMain() { return main; }
public void setMain(String main) { this.main = main; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
}

MainActivity.java

package com.dhanurjan.weather;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.dhanurjan.weather.Retrofit.ApiClient;
import com.dhanurjan.weather.Retrofit.ApiInterface;
import com.dhanurjan.weather.Retrofit.Example;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
Button searchBtn;
TextView tempText , feelText , humidityText, lon, lat, country, sunrise, sunset, descText;
EditText cityName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
searchBtn = findViewById(R.id.searchBtn);
tempText = findViewById(R.id.tempText);
feelText = findViewById(R.id.feelText);
humidityText = findViewById(R.id.humidityText);
country = findViewById(R.id.country);
sunrise = findViewById(R.id.sunrise);
sunset = findViewById(R.id.sunset);
lon = findViewById(R.id.lonText);
lat = findViewById(R.id.latText);
cityName = findViewById(R.id.cityName);
descText = findViewById(R.id.descText);

searchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

getWeatherData(cityName.getText().toString().trim());
}
});
}
private void getWeatherData(String name){
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Example> call = apiInterface.getWeatherData(name);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(Call<Example> call, Response<Example> response) {
tempText.setText("Temperature :"+" "+response.body().getMain().getTemp()+" ℃");
feelText.setText("Feels Like :"+" "+response.body().getMain().getFeels_like()+" ℃");
lon.setText("Longitude :"+" "+response.body().getCoord().getLon()+" °E");
lat.setText("Latitude :"+" "+response.body().getCoord().getLat()+" °N");
humidityText.setText("Humidity :"+" "+response.body().getMain().getHumidity()+" %");
country.setText("country :"+" "+response.body().getSys().getCountry());
sunrise.setText("sunrise :"+" "+response.body().getSys().getSunrise()+" AM");
sunset.setText("sunset :"+" "+response.body().getSys().getSunset()+" PM");
descText.setText("descText :"+" "+response.body().getWeather().getDescription());

}
@Override
public void onFailure(Call<Example> call, Throwable t) {
}
});
}
}


代码的主要问题是:

@SerializedName("weather")
private Weather weather;

对应的JSON是:

"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}]

虽然它只有1个项,但它实际上是Weather对象的JSON数组,因为";["one_answers"]";

改装注释需要更改为:

@SerializedName("weather")
private List<Weather> weatherList;

getter和setter需要更改为:

public List<Weather> getWeatherList() { return weatherList; }
public void setWeatherList(List<Weather> weatherList) { this.weatherList = weatherList; }

显示天气信息的代码需要更新为:

response.body().getWeatherList().get(0).getDescription();

这将获得第一个Weather对象,如果没有,则会崩溃。

但我的项目中正在运行您的代码,所以如果您遇到任何其他问题,请告诉我。

最后,对于任何正在寻找更简单的API来学习改装的人来说:https://dog.ceo/api/breeds/image/random

这是一个只返回2个字段的GET。

最新更新