最近,我决定学习一下如何编写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()
}
}