Android Retrofit2 Kotlin 无法将列表值设置为响应
Android Retrofit2 Kotlin can't set list value equal to Response
我在从变量中的 Facebook API 获取数据时遇到问题。在我的主 activity 中,我调用 viewModel.getFeed()
。记录器 returns 为空,但 OkHttp returns 是我想要的响应。如何使用此响应数据填充列表?
FacebookAPI服务
interface FacebookAPIService {
// Get all the english movies in given year
@GET("USER_ID/feed?access_token=ACCESS_TOKEN")
fun getUserFeed(): Call<NewsItemData>
}
FacebookAPI
class FacebookAPI {
companion object {
private const val baseUrl = "https://graph.facebook.com/v5.0/"
/**
* @return [FacebookAPIService] The service class off the retrofit client
*/
fun createApi(): FacebookAPIService {
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build()
// Create retrofit instance
val facebookApi = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
// Return the retrofit FacebookAPIService
return facebookApi.create(FacebookAPIService::class.java)
}
}
}
NewsRepository
class NewsRepository(context: Context) {
private val facebookApi: FacebookAPIService = FacebookAPI.createApi()
fun getUserFeed() = facebookApi.getUserFeed()
...
MainActivityViewModel
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
private val newsItemsRepository = NewsRepository(application.applicationContext)
val newsItems = MutableLiveData<List<NewsItem>>()
private fun getFeed() {
newsItemsRepository.getUserFeed().enqueue(object : Callback<NewsItemData?> {
override fun onResponse(call: Call<NewsItemData?>, response: Response<NewsItemData?>) {
if (response.isSuccessful) {
newsItems.value = response.body()!!.results
Log.d("response", newsItems.value.toString())
} else {
error.value = "An error has occurred: ${response.errorBody().toString()}"
Log.e("response", response.toString())
}
}
override fun onFailure(call: Call<NewsItemData?>, t: Throwable) {
error.value = t.message
}
})
}
}
NewsItem
@Parcelize
@Entity(tableName = "news_item")
data class NewsItem(
@SerializedName("message") var message: String,
@SerializedName("story") var story: String,
@PrimaryKey(autoGenerate = true) val id: Long? = null
) : Parcelable
NewsItemData
class NewsItemData {
var results: List<NewsItem>? = null
}
为了提供更多背景信息,我的回复如下所示:
{
"data": [
...
{
"created_time": "some timestamp",
"id": "some id"
},
{
"message": "some messge",
"created_time": "some timestamp",
"id": "some id"
}
...
],
"paging": {
...
}
}
这是我的响应解析代码json
if (response.isSuccessful) {
response.body()?.let { body ->
results=body
Log.d("API RESULT"," $results")
}
} else {
var bodyError=response.errorBody()?.string()?:"Error connection with server"
try {
//use this to parse json at error response
val message=JSONObject(bodyError)
bodyError = if (message.has("message"))
message.getString("message")
else
"Error connection with server"
}catch (ex: JSONException) {
Log.e("API NOT JSON"," $bodyError")
}
Log.e("API ERROR"," $bodyError")
}
希望对您有所帮助
这里的问题是您必须将 @SerializedName
添加到 NewsItemData results
字段。
NewsItemData
class NewsItemData {
@SerializedName("data") var results: List<NewsItem>? = null
}
否则 JSON 数组将无法按您的预期正确映射到列表。
我在从变量中的 Facebook API 获取数据时遇到问题。在我的主 activity 中,我调用 viewModel.getFeed()
。记录器 returns 为空,但 OkHttp returns 是我想要的响应。如何使用此响应数据填充列表?
FacebookAPI服务
interface FacebookAPIService {
// Get all the english movies in given year
@GET("USER_ID/feed?access_token=ACCESS_TOKEN")
fun getUserFeed(): Call<NewsItemData>
}
FacebookAPI
class FacebookAPI {
companion object {
private const val baseUrl = "https://graph.facebook.com/v5.0/"
/**
* @return [FacebookAPIService] The service class off the retrofit client
*/
fun createApi(): FacebookAPIService {
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build()
// Create retrofit instance
val facebookApi = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
// Return the retrofit FacebookAPIService
return facebookApi.create(FacebookAPIService::class.java)
}
}
}
NewsRepository
class NewsRepository(context: Context) {
private val facebookApi: FacebookAPIService = FacebookAPI.createApi()
fun getUserFeed() = facebookApi.getUserFeed()
...
MainActivityViewModel
class MainActivityViewModel(application: Application) : AndroidViewModel(application) {
private val newsItemsRepository = NewsRepository(application.applicationContext)
val newsItems = MutableLiveData<List<NewsItem>>()
private fun getFeed() {
newsItemsRepository.getUserFeed().enqueue(object : Callback<NewsItemData?> {
override fun onResponse(call: Call<NewsItemData?>, response: Response<NewsItemData?>) {
if (response.isSuccessful) {
newsItems.value = response.body()!!.results
Log.d("response", newsItems.value.toString())
} else {
error.value = "An error has occurred: ${response.errorBody().toString()}"
Log.e("response", response.toString())
}
}
override fun onFailure(call: Call<NewsItemData?>, t: Throwable) {
error.value = t.message
}
})
}
}
NewsItem
@Parcelize
@Entity(tableName = "news_item")
data class NewsItem(
@SerializedName("message") var message: String,
@SerializedName("story") var story: String,
@PrimaryKey(autoGenerate = true) val id: Long? = null
) : Parcelable
NewsItemData
class NewsItemData {
var results: List<NewsItem>? = null
}
为了提供更多背景信息,我的回复如下所示:
{
"data": [
...
{
"created_time": "some timestamp",
"id": "some id"
},
{
"message": "some messge",
"created_time": "some timestamp",
"id": "some id"
}
...
],
"paging": {
...
}
}
这是我的响应解析代码json
if (response.isSuccessful) {
response.body()?.let { body ->
results=body
Log.d("API RESULT"," $results")
}
} else {
var bodyError=response.errorBody()?.string()?:"Error connection with server"
try {
//use this to parse json at error response
val message=JSONObject(bodyError)
bodyError = if (message.has("message"))
message.getString("message")
else
"Error connection with server"
}catch (ex: JSONException) {
Log.e("API NOT JSON"," $bodyError")
}
Log.e("API ERROR"," $bodyError")
}
希望对您有所帮助
这里的问题是您必须将 @SerializedName
添加到 NewsItemData results
字段。
NewsItemData
class NewsItemData {
@SerializedName("data") var results: List<NewsItem>? = null
}
否则 JSON 数组将无法按您的预期正确映射到列表。