本文介绍了应为BEGIN_ARRAY,但在第1行第2列路径$JSON Array Kotline处为BEGIN_OBJECT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想检索一个JSON Array,如何调整我的代码库以适应它。我使用了改进库来检索数据,并使用了MVVM架构。我收到错误,应为BEGIN_ARRAY,但在第1行第2列路径$处为BEGIN_OBJECT。
这是我的终结点类:
@GET("v2/venues/search")
fun fetchAllVenues(): Call<List<Venue>>
}
这是我的存储库类:
class VenueRepository {
private var apiInterface: VenuesEndpoint? = null
init {
apiInterface = ApiClient.getApiClient().create(VenuesEndpoint::class.java)
}
fun fetchAllVenues(): MutableLiveData<List<Venue>?> {
val data = MutableLiveData<List<Venue>?>()
apiInterface?.fetchAllVenues()?.enqueue(object : Callback<List<Venue>> {
override fun onFailure(call: Call<List<Venue>>, t: Throwable) {
data.value = null
}
override fun onResponse(
call: Call<List<Venue>>,
response: Response<List<Venue>>
) {
val res = response.body()
if (response.code() == 200 && res != null) {
data.value = res
} else {
data.value = null
}
}
})
return data
}
}
这是我的模型类:
data class Venue(var id:Int,var name:String)
这是我的viewmodel类:
class VenueViewModel : ViewModel() {
private var venueRepository: VenueRepository? = null
var postModelListLiveData: MutableLiveData<List<Venue>?>? = null
init {
venueRepository = VenueRepository()
postModelListLiveData = MutableLiveData()
}
fun fetchAllVenues() {
postModelListLiveData = venueRepository?.fetchAllVenues()
}
}
这是我要检索的JSON:
"response": { "venues": [ { "id": "4b83cb72f964a520d71031e3" "name": "Stadhuis" "contact": { "phone": "+3114010" "formattedPhone": "+31 14010" "twitter": "rotterdam" } "location": { "address": "Coolsingel 40" "lat": 51.92258962728412 "lng": 4.480227190204032 "labeledLatLngs": [ "0": { "label": "display" "lat": 51.92258962728412 "lng": 4.480227190204032 } ] "postalCode": "3011 AD" "cc": "NL" "city": "Rotterdam" "state": "Zuid-Holland" "country": "Nederland" "formattedAddress": [ "0": "Coolsingel 40" "1": "3011 AD Rotterdam" "2": "Nederland"
推荐答案
问题是,响应返回venues
,而您期望的是List<Venue>
,因此,您应该可以创建另一个数据类,如下所示:
data class Venues(
val venues: List<Venue>
)
,然后在GET
请求返回Call<Venues>
内请务必告知这是否能为您解决问题:)
更新
好的,我们的谈话有点长,但最终这是您的详细解决方案,希望这能为您解决所有问题!
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
class ViewModel : ViewModel() {
private val repository = Repository()
fun getData(longLat: String, date: String): LiveData<mainResponse?> {
repository.fetch(longLat, date)
return repository.data
}
}
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class Repository {
private val _data: MutableLiveData<mainResponse?> = MutableLiveData(null)
val data: LiveData<mainResponse?> get() = _data
fun fetch(longlat: String, date: String) {
val retrofit = Retro()
val api = retrofit.retro.create(api::class.java)
api.get(
longLat = longlat,
date = date
).enqueue(object : Callback<mainResponse>{
override fun onResponse(call: Call<mainResponse>, response: Response<mainResponse>) {
val res = response.body()
if (response.code() == 200 && res != null) {
_data.value = res
} else {
_data.value = null
}
}
override fun onFailure(call: Call<mainResponse>, t: Throwable) {
_data.value = null
}
})
}
}
private val viewModel by viewModels<ViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.getData(
longLat = "40.7,-74", // sample latitude and longitude
date = "20210715" // date format is: YYYYMMDD
).observe(this, Observer {
it?.let { res ->
res.response.venues.forEach { venue ->
val name = venue.name
val location = venue.location
Log.d("name ",name)
Log.d("address ", location.address)
}
}
})
}
}
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface api {
@GET("v2/venues/search")
fun get(
@Query("ll") longLat: String,
@Query("client_id") id: String = Const.clientId,
@Query("client_secret") secret: String = Const.clientSecret,
@Query("v") date: String
): Call<mainResponse>
}
数据类mainResponse(VAL响应:响应)data class Response(
val venues: List<Venue>,
val confident: Boolean
)
data class Location(
val address: String,
val crossStreet: String,
val lng: Double,
val lat: Double
)
data class Venue(
val id: String,
val name: String,
val location: Location
)
object Const {
const val BASE_URL = "https://api.foursquare.com"
const val clientId = "" // add yours
const val clientSecret = "" // add yours
}
class Retro {
val retro = Retrofit.Builder()
.baseUrl(Const.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
def coroutines_version = "1.4.2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutines_version"
def lifecycle_version = "2.3.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "androidx.activity:activity-ktx:1.2.3"
这篇关于应为BEGIN_ARRAY,但在第1行第2列路径$JSON Array Kotline处为BEGIN_OBJECT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!