Retrofit enqueue方法中无法返回填充后的ArrayList问题排查
问题原因
Retrofit的enqueue()是异步执行的:网络请求会在后台线程处理,主线程不会等待请求完成,会直接执行后续代码。你调用return templList和打印日志的时候,onResponse()回调还没触发,所以返回的是空数组,日志也显示[]。
解决方案
方案1:使用回调接口
修改方法逻辑,不直接返回数组,而是通过回调接口在请求完成后传递数据:
// 定义回调接口 interface OnAudioLoadedListener { fun onLoaded(audioList: ArrayList<Music>) fun onFailed(error: String) } private fun getAllAudio(listener: OnAudioLoadedListener) { val service = SongFactory.makeSongLists() service.getAllSongs().enqueue(object : Callback<ArrayList<Music>>{ override fun onResponse( call: Call<ArrayList<Music>>, response: Response<ArrayList<Music>> ) { val tempList = ArrayList<Music>() response.body()?.forEach { items -> val music = Music(items.album,items.artist,items.duration,items.id,items.path,items.songuri,items.title) tempList.add(music) } listener.onLoaded(tempList) } override fun onFailure(call: Call<ArrayList<Music>>, t: Throwable) { val errorMsg = t.message ?: "未知错误" Toast.makeText(this@MainActivity, "Error $errorMsg", Toast.LENGTH_SHORT).show() listener.onFailed(errorMsg) } }) } // 调用示例 getAllAudio(object : OnAudioLoadedListener { override fun onLoaded(audioList: ArrayList<Music>) { // 在这里处理填充好的数组,比如更新UI、打印日志 Log.d("get", audioList.toString()) } override fun onFailed(error: String) { // 处理错误逻辑 } })
方案2:使用Kotlin协程(推荐)
Retrofit支持协程,将网络请求转为同步写法,代码更简洁:
第一步:修改Retrofit接口
给接口方法添加suspend关键字:
interface SongService { // 替换成你的实际接口路径 @GET("songs") suspend fun getAllSongs(): ArrayList<Music> }
第二步:改造getAllAudio为挂起函数
private suspend fun getAllAudio(): ArrayList<Music> { val tempList = ArrayList<Music>() try { val service = SongFactory.makeSongLists() val songList = service.getAllSongs() songList.forEach { items -> val music = Music(items.album,items.artist,items.duration,items.id,items.path,items.songuri,items.title) tempList.add(music) } } catch (t: Throwable) { Toast.makeText(this@MainActivity, "Error ${t.message}", Toast.LENGTH_SHORT).show() } Log.d("get", tempList.toString()) return tempList }
第三步:在协程作用域内调用
比如在Activity/Fragment中使用lifecycleScope:
lifecycleScope.launch { val audioList = getAllAudio() // 在这里处理获取到的数组 }
内容的提问来源于stack exchange,提问作者coppersmith
相关产品推荐
相关产品推荐

