改造 API 调用 returns 空
Retrofit API call returns null
这是我尝试使用的 API/JSON 数据:https://pogoapi.net/api/v1/pokemon_names.json
问题是,当我尝试解析 JSON 响应时,只返回 null。
型号:
data class ListOfReleasedPokemon(
val releasedPokemon: List<PokemonResponse>
)
data class PokemonResponse(
val pokemonMap: Map<String, ReleasedPokemonModel>
)
data class ReleasedPokemonModel(
val id: Int,
val name: String
)
API 通话:
interface PogoApi {
@GET("released_pokemon.json")
suspend fun getReleasedPokemon(): ListOfReleasedPokemon
}
应用程序模块:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun providePokemonRepository(
pogoApi: PogoApi
) = PokemonRepository(pogoApi)
@Singleton
@Provides
fun providePogoApi(): PogoApi{
// val gson = GsonBuilder()
// .registerTypeAdapter(ReleasedPokemonModel::class.java, JsonDeserializer())
// .create()
return Retrofit.Builder()
.baseUrl(POGO_API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(PogoApi::class.java)
}
}
Repository(发现错误的地方):
@ActivityScoped
class PokemonRepository @Inject constructor(
private val pogoApi: PogoApi
){
suspend fun getReleasedPokemonList(): Resource<ListOfReleasedPokemon> {
val response = try{
pogoApi.getReleasedPokemon()
// Returns null
} catch(e: IOException){
return Resource.Error("Please check your internet connection")
} catch(e: HttpException){
return Resource.Error("Unexpected response")
}
Log.d("MainActivity", "GetPokemonReleasedList Run with no errors")
return Resource.Success(data = response)
}
}
如有任何帮助,我们将不胜感激!
哦,我现在才注意到你似乎有一个与这个 Json 解析器相关的问题。
好吧,在这条评论中,我将详细指导您完成您的这个项目。
因为上一个问题你只问了如何解析 Json with undefined key.
首先,创建一个自定义 Json 反序列化器。因为这里你的数据 api 有一个未定义的键。在这里,我将使用自定义 Json 反序列化器创建 1 个 gson。如下:
精灵宝可梦反应
data class PokemonResponse(
val pokemonMap: List<StringReleasedPokemonModel>
)
data class ReleasedPokemonModel(
val id: Int,
val name: String
)
GsonHelper.kt
object GsonHelper {
fun create(): Gson = GsonBuilder().apply {
registerTypeAdapter(PokemonResponse::class.java, PokemonType())
setLenient()
}.create()
private class PokemonType : JsonDeserializer<PokemonResponse> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): PokemonResponse {
val list = mutableListOf<ReleasedPokemonModel>()
// Get your all key
val keys = json?.asJsonObject?.keySet()
keys?.forEach { key ->
// Get your item with key
val item = Gson().fromJson<ReleasedPokemonModel>(
json.asJsonObject[key],
object : TypeToken<ReleasedPokemonModel>() {}.type
)
list.add(item)
}
return PokemonResponse(list)
}
}
}
接下来,将此 Gson 提供给您的 Dagger 或 Hilt。
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideGson(): Gson = GsonHelper.create()
...
}
然后你修改你的addConverterFactory
如下:
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideGson(): Gson = GsonHelper.create()
@Singleton
@Provides
fun providePogoApi(gson: Gson): PogoApi = Retrofit.Builder()
.baseUrl(POGO_API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(PogoApi::class.java)
}
在PogoApi
中,将getReleasedPokemon()
的return类型改为PokemonResponse
。
interface PogoApi {
@GET("released_pokemon.json")
suspend fun getReleasedPokemon(): PokemonResponse
}
最后,在您的存储库中,编辑以下内容:
PokemonRepository.kt
@ActivityScoped
class PokemonRepository @Inject constructor(
private val pogoApi: PogoApi
){
suspend fun getReleasedPokemonList(): Resource<PokemonResponse> = try {
val response = pogoApi.getReleasedPokemon()
Log.d("MainActivity", "list: ${response}")
Resource.Success(data = response)
} catch(e: IOException){
Resource.Error("Please check your internet connection")
} catch(e: HttpException){
Resource.Error("Unexpected response")
}
}
这是我尝试使用的 API/JSON 数据:https://pogoapi.net/api/v1/pokemon_names.json
问题是,当我尝试解析 JSON 响应时,只返回 null。
型号:
data class ListOfReleasedPokemon(
val releasedPokemon: List<PokemonResponse>
)
data class PokemonResponse(
val pokemonMap: Map<String, ReleasedPokemonModel>
)
data class ReleasedPokemonModel(
val id: Int,
val name: String
)
API 通话:
interface PogoApi {
@GET("released_pokemon.json")
suspend fun getReleasedPokemon(): ListOfReleasedPokemon
}
应用程序模块:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Singleton
@Provides
fun providePokemonRepository(
pogoApi: PogoApi
) = PokemonRepository(pogoApi)
@Singleton
@Provides
fun providePogoApi(): PogoApi{
// val gson = GsonBuilder()
// .registerTypeAdapter(ReleasedPokemonModel::class.java, JsonDeserializer())
// .create()
return Retrofit.Builder()
.baseUrl(POGO_API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(PogoApi::class.java)
}
}
Repository(发现错误的地方):
@ActivityScoped
class PokemonRepository @Inject constructor(
private val pogoApi: PogoApi
){
suspend fun getReleasedPokemonList(): Resource<ListOfReleasedPokemon> {
val response = try{
pogoApi.getReleasedPokemon()
// Returns null
} catch(e: IOException){
return Resource.Error("Please check your internet connection")
} catch(e: HttpException){
return Resource.Error("Unexpected response")
}
Log.d("MainActivity", "GetPokemonReleasedList Run with no errors")
return Resource.Success(data = response)
}
}
如有任何帮助,我们将不胜感激!
哦,我现在才注意到你似乎有一个与这个 Json 解析器相关的问题。
好吧,在这条评论中,我将详细指导您完成您的这个项目。 因为上一个问题你只问了如何解析 Json with undefined key.
首先,创建一个自定义 Json 反序列化器。因为这里你的数据 api 有一个未定义的键。在这里,我将使用自定义 Json 反序列化器创建 1 个 gson。如下:
精灵宝可梦反应
data class PokemonResponse(
val pokemonMap: List<StringReleasedPokemonModel>
)
data class ReleasedPokemonModel(
val id: Int,
val name: String
)
GsonHelper.kt
object GsonHelper {
fun create(): Gson = GsonBuilder().apply {
registerTypeAdapter(PokemonResponse::class.java, PokemonType())
setLenient()
}.create()
private class PokemonType : JsonDeserializer<PokemonResponse> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): PokemonResponse {
val list = mutableListOf<ReleasedPokemonModel>()
// Get your all key
val keys = json?.asJsonObject?.keySet()
keys?.forEach { key ->
// Get your item with key
val item = Gson().fromJson<ReleasedPokemonModel>(
json.asJsonObject[key],
object : TypeToken<ReleasedPokemonModel>() {}.type
)
list.add(item)
}
return PokemonResponse(list)
}
}
}
接下来,将此 Gson 提供给您的 Dagger 或 Hilt。
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideGson(): Gson = GsonHelper.create()
...
}
然后你修改你的addConverterFactory
如下:
AppModule.kt
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideGson(): Gson = GsonHelper.create()
@Singleton
@Provides
fun providePogoApi(gson: Gson): PogoApi = Retrofit.Builder()
.baseUrl(POGO_API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(PogoApi::class.java)
}
在PogoApi
中,将getReleasedPokemon()
的return类型改为PokemonResponse
。
interface PogoApi {
@GET("released_pokemon.json")
suspend fun getReleasedPokemon(): PokemonResponse
}
最后,在您的存储库中,编辑以下内容:
PokemonRepository.kt
@ActivityScoped
class PokemonRepository @Inject constructor(
private val pogoApi: PogoApi
){
suspend fun getReleasedPokemonList(): Resource<PokemonResponse> = try {
val response = pogoApi.getReleasedPokemon()
Log.d("MainActivity", "list: ${response}")
Resource.Success(data = response)
} catch(e: IOException){
Resource.Error("Please check your internet connection")
} catch(e: HttpException){
Resource.Error("Unexpected response")
}
}