You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成Flow后Retrofit无法返回数据的问题排查与解决

Android Flow + Retrofit 异步数据加载失效问题排查与解决

近期学习Android开发时,遇到一个问题:编写的REST接口数据获取+RecyclerView展示代码,硬编码数据时功能正常,用Retrofit的enqueue方法能在日志中看到返回数据,但改用Flow处理异步数据后,功能失效且日志为空。相关代码如下:

ApiInterface 代码

interface ApiInterface {
    @GET("/api/v1/employees")
    fun getEmployees() : Call<ResponseModel>
}

ServiceBuilder 代码

object ServiceBuilder {
    private val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
            .setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()

    private val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build()

    fun<T> buildService(service: Class<T>): T{
        return retrofit.create(service)
    }
}

EmployeeRepository 代码

class EmployeeRepository() {
    fun getEmployees(): Flow<ResponseModel?> = flow {
        val response = ServiceBuilder.buildService(ApiInterface::class.java)
        Log.d("restAPI",response.getEmployees().execute().body()!!.toString() )
        emit( response.getEmployees().execute().body() )
    }
}

MainViewModel 代码

class MainViewModel(private val savedStateHandle: SavedStateHandle): ViewModel() {

    init {
        viewModelScope.launch {
            EmployeeRepository().getEmployees().collect {
                Log.d("restAPI", it.toString())
            }
        }
    }
}

MainActivity 代码

class MainActivity : AppCompatActivity() {
    private val mainModel: MainViewModel by viewModels()

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.recyclerView.layoutManager = LinearLayoutManager(this)

        val employee = EmployeeModel(id = 1, employee_age = 11, employee_salary = 12,
                                     employee_name = "ABCD", profile_image = "")
        var employeeList = mutableListOf(employee)
        val adapter = EmployeeListAdapter(employeeList)
        binding.recyclerView.adapter = adapter
    }
}

问题解决方法

感谢ho3einshah的帮助,关键修改如下:

  1. 修改ApiInterface定义:将返回类型从Call改为Response,并添加suspend关键字
interface ApiInterface {
    @GET("/api/v1/employees")
    suspend fun getEmployees() : Response<ResponseModel>
}
  1. 调整ViewModel逻辑:将init块中的收集逻辑改为暴露getData方法,返回Repository的Flow
fun getData() = repository.getEmployees()
  1. Activity中正确收集Flow:使用lifecycleScope配合repeatOnLifecycle在合适的生命周期状态下收集数据,并更新RecyclerView适配器
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        mainModel.getData().collect { employeeList ->
            Log.d("restAPI", employeeList.toString() )
            val adapter = EmployeeListAdapter(employeeList)
            binding.recyclerView.adapter = adapter
        }
    }
}

修改后已能正常在界面上展示获取到的数据。

内容的提问来源于stack exchange,提问作者Mnemonic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:45:28