Android使用Retrofit对接PokeAPI:如何从请求回调取参获取宝可梦图片
可直接落地的实现方案
第一步:从现有回调中拿到name字段
你在世代接口的onResponse里拿到的DataResponse已经带了全部宝可梦的名称数据,根本不需要费劲把值从回调里掏出来存成全局变量,直接在当前回调的作用域里遍历取就行:
在你现在写的那行Timber日志下面加这段代码:
// 把每个宝可梦的name提取成单独的列表 val pokemonNames = DataResponse.pokemon_species.map { it.name } // 打个日志确认下是不是取对了 Timber.i("拿到的宝可梦名称列表:%s", pokemonNames)
第二步:拿着name去请求对应的图片资源
你已经定义好了getArtwork接口,直接遍历刚才拿到的名称列表,挨个发请求就行,全程不用跨作用域传值:
pokemonNames.forEach { name -> jsonPlaceholderApi.getArtwork(name).enqueue(object : Callback<PokemonArtwork> { override fun onResponse(call: Call<PokemonArtwork>, response: Response<PokemonArtwork>) { val pokemonDetail = response.body() ?: return // 这里同时有请求用的name、接口返回的图片资源,直接用就行 Timber.i("宝可梦%s的图片地址:%s", name, pokemonDetail.sprites.front_default) } override fun onFailure(call: Call<PokemonArtwork>, t: Throwable) { Timber.e("获取%s的图片失败:%s", name, t.message) } }) }
几个容易踩的坑
- 别为了把name移出回调去搞全局变量、跨页面透传,这种写法很容易引发内存泄漏,你现在的需求完全可以在回调的链式作用域里走完所有逻辑,没必要搞复杂。
- 第一世代一共151个宝可梦,一次性把所有请求都发出去很容易被接口限流,最好加个简单的并发控制,比如每次最多同时发5个请求,能大幅降低请求失败的概率。
- 记得把
PokemonArtwork的数据类和接口返回的sprites嵌套结构对齐,不然Gson解析的时候会把图片字段读成null,到时候找半天bug都找不到原因。
内容的提问来源于stack exchange,提问作者BBBBeloved
相关产品推荐
相关产品推荐

