Im try to retrieve some data from api OpenWeatherApp im using Kotlin but i got this error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
i need to know how can i call the json_object instead the json_array
Adapter
class WeatherAdapter (
var weather: List<Weather>)
: RecyclerView.Adapter<WeatherAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = WeatherItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val weather = weather[position]
holder.bind(weather)
}
override fun getItemCount() = weather.size
class ViewHolder(private val binding: WeatherItemBinding):
RecyclerView.ViewHolder(binding.root) {
fun bind(weatherInfo: Weather) {
binding.weatherName.text = weatherInfo.name
binding.weatherName.text = weatherInfo.base
binding.weatherName.text = weatherInfo.wind.speed.toString()
}
}
}
Activity
open class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val weatherAdapter = WeatherAdapter(emptyList())
binding.recycler.adapter = weatherAdapter
lifecycleScope.launch {
val weather = WeatherDbClient.service?.listWeatherApp()
val body = withContext(Dispatchers.IO) {
weather?.execute()?.body()
}
if(body != null){
weatherAdapter.weather = body
weatherAdapter.notifyDataSetChanged()
}
}
}
}
interface
interface WeatherService {
@GET("weather?APPID=$API_KEY&q=$CITY_WEATHER")
fun listWeatherApp(): Call<List<Weather>>
}
Objetct
object WeatherDbClient {
private val interceptor =
HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
private val http = OkHttpClient.Builder()
.addInterceptor(interceptor)
.build()
private val retrofit = Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(GsonConverterFactory.create())
.client(http)
.build()
val service: WeatherService? = retrofit.create(WeatherService::class.java)
}
CodePudding user response:
that's error happens to me twice
- if there's an null value from api
- if the corresponding datatype is not match the api value data type for example : id:Int maybe that's will got this error because the api value is huge number and we should use BigDecimal datatype
CodePudding user response:
I guess your response models are wrong. Try the following models:
data class WeatherResponse (
@SerializedName("weather") var weather: ArrayList<Weather> = arrayListOf(),
@SerializedName("base") var base: String? = null,
@SerializedName("main") var main: Main? = Main(),
@SerializedName("visibility") var visibility : Int? = null,
@SerializedName("wind") var wind: Wind? = Wind(),
@SerializedName("clouds") var clouds: Clouds? = Clouds(),
@SerializedName("dt") var dt: Int? = null,
@SerializedName("sys") var sys: Sys? = Sys(),
@SerializedName("id") var id: Int? = null,
@SerializedName("name") var name: String? = null,
@SerializedName("cod") var cod: Int? = null
)
data class Weather (
@SerializedName("id" ) var id : Int? = null,
@SerializedName("main" ) var main : String? = null,
@SerializedName("description" ) var description : String? = null,
@SerializedName("icon" ) var icon : String? = null
)
data class Main (
@SerializedName("temp" ) var temp : Double? = null,
@SerializedName("pressure" ) var pressure : Int? = null,
@SerializedName("humidity" ) var humidity : Int? = null,
@SerializedName("temp_min" ) var tempMin : Double? = null,
@SerializedName("temp_max" ) var tempMax : Double? = null
)
data class Wind (
@SerializedName("speed" ) var speed : Double? = null,
@SerializedName("deg" ) var deg : Int? = null
)
data class Clouds (
@SerializedName("all" ) var all : Int? = null
)
data class Sys (
@SerializedName("type" ) var type : Int? = null,
@SerializedName("id" ) var id : Int? = null,
@SerializedName("message" ) var message : Double? = null,
@SerializedName("country" ) var country : String? = null,
@SerializedName("sunrise" ) var sunrise : Int? = null,
@SerializedName("sunset" ) var sunset : Int? = null
)
And the request should be:
interface WeatherService {
@GET("weather?APPID=$API_KEY&q=$CITY_WEATHER")
fun listWeatherApp(): Call<WeatherResponse>
}
NOTE: there is a handy JSON converter to Kotlin Data Classes.
