添加Flow后的Retrofit不返回值



最近,我决定学习一下如何编写android应用程序。在阅读书籍和查看许多代码,博客等之后。我准备了一个小代码,它应该从rest服务中获取数据列表,并在recyclerView的屏幕上显示它们。它与"硬编码数据"一起工作,在添加改造后,我已经在Log中看到了数据,因为我使用了带有onResponse方法的enqueue。但它是异步调用,因此我添加了Flow的emit和collect方法来处理传入的数据。不幸的是,它仍然不工作,现在甚至日志是空的。

interface ApiInterface {
@GET("/api/v1/employees")
fun getEmployees() : Call<ResponseModel>
}
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)
}
}
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() )
}
}
class MainViewModel(private val savedStateHandle: SavedStateHandle): ViewModel() {
init {
viewModelScope.launch {
EmployeeRepository().getEmployees().collect {
Log.d("restAPI", it.toString())
}
}
}
}
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!对于所有对现在和将来感兴趣的人,我想通知从Call到Response的更改:
interface ApiInterface {
@GET("/api/v1/employees")
suspend fun getEmployees() : Response<ResponseModel>
}

并将init改为getData方法:

fun getData() = repository.getEmployees()

是解决问题的线索。此外,我在AppCompatActivity中调用了livecycleScope,用于将数据直接传递给适配器:

lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
mainModel.getData().collect { employeeList ->
Log.d("restAPI", employeeList.toString() )
val adapter = EmployeeListAdapter(employeeList)
binding.recyclerView.adapter = adapter
}
}
}

现在我看到屏幕上有传入数据的列表。

你好,希望这个答案对你有所帮助。首先,因为使用GsonConverterFactory添加这个依赖到你的build.gradle(app):实现"com.squareup.retrofit2: converter-gson: 2.9.0"现在将您的API服务更改为以下代码:

import retrofit2.Response
import retrofit2.http.GET
interface ApiInterface {
@GET("/api/v1/employees")
suspend fun getList() : Response<ResponseModel>

请注意回复必须来自retrofit2。响应

我已经使用了你正在使用的api。作为回应,你有一个"数据"列表;json的关键。根据Json Response创建响应模型:

data class ResponseModel(
var status : String?,
var data : ArrayList<EmployeeModel>

)

现在这是EmployeeModel:

data class EmployeeModel(
var d:Long,
var employee_age:Long,
var employee_salary:Long,
var employee_name:String,
var profile_image:String

)

class EmployeeRepository {
fun getEmployees() = flow<Response<EmployeeModel>> {
val response = RetrofitBuilder.buildService(MainService::class.java).getEmployees()
Log.e("response",response.body()?.data.toString())
}

}

和你的viewModel最好从一个方法调用repository,而不是在init块中:

class MainViewModel : ViewModel() {
private val repository = EmployeeRepository()
fun getData() {
viewModelScope.launch(Dispatchers.IO) {
val a =  repository.getEmployees()
.collect{
}
}
}

}

和在MainActivity中像这样初始化MainViewModel并调用MainViewModel方法:

class MainActivity : AppCompatActivity() {
lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
mainViewModel.getData()
}

}

最新更新