无法为 retrofit2.Call MVVM Coroutines Retrofit 调用无参数构造函数

Unable to invoke no-args constructor for retrofit2.Call MVVM Coroutines Retrofit

我想在我的项目中使用协程,只有当我使用协程时出现错误:无法调用无参数构造函数。我不知道为什么会出现此错误。我也是协程的新手。

这是我的apiclient class:

class ApiClient {

    val retro = Retrofit.Builder()
        .baseUrl(Constants.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
}

这是我的端点class:

@GET("v2/venues/search")
  suspend   fun get(
        @Query("near") city: String,
        @Query("limit") limit: String = Constants.limit,
        @Query("radius") radius: String = Constants.radius,
        @Query("client_id") id: String = Constants.clientId,
        @Query("client_secret") secret: String = Constants.clientSecret,
        @Query("v") date: String
    ): Call<VenuesMainResponse>

我的存储库class:

class VenuesRepository() {

    private val _data: MutableLiveData<VenuesMainResponse?> = MutableLiveData(null)
    val data: LiveData<VenuesMainResponse?> get() = _data


   suspend fun fetch(city: String, date: String)  {

        val retrofit = ApiClient()
        val api = retrofit.retro.create(VenuesEndpoint::class.java)

        api.get(
            city = city,
            date = date
        ).enqueue(object : Callback<VenuesMainResponse>{

            override fun onResponse(call: Call<VenuesMainResponse>, response: Response<VenuesMainResponse>) {

                val res = response.body()
                if (response.code() == 200 && res != null) {

                    _data.value = res

                } else {

                    _data.value = null
                }
            }

            override fun onFailure(call: Call<VenuesMainResponse>, t: Throwable) {
                _data.value = null
            }
        })
    }

}

我的 ViewModel class:

class VenueViewModel( ) : ViewModel() {

    private val repository = VenuesRepository()

    fun getData(city: String, date: String): LiveData<VenuesMainResponse?> {
        viewModelScope.launch {
            try {
                repository.fetch(city, date)

            } catch (e: Exception) {
                Log.d("Hallo", "Exception: " + e.message)
            }
        }
        return repository.data
    }

}

activity的一部分class:

class MainActivity : AppCompatActivity(){
    private lateinit var venuesViewModel: VenueViewModel
    private lateinit var adapter: HomeAdapter
    private var searchData: List<Venue>? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val editText = findViewById<EditText>(R.id.main_search)
        venuesViewModel = ViewModelProvider(this)[VenueViewModel::class.java]
        venuesViewModel.getData(
            city = "",
            date = ""
        ).observe(this, Observer {

            it?.let { res ->
                initAdapter()
                rv_home.visibility = View.VISIBLE
                adapter.setData(it.response.venues)
                searchData = it.response.venues
                println(it.response.venues)
            }
        })

这是我的 VenuesMainResponse 数据class

data class VenuesMainResponse(
    val response: VenuesResponse
)

我认为 no-args constructor 警告应该与您的 VenuesMainResponse 有关,是 data class 吗?您还应该为其添加代码以及完整的 Log details

此外,对于 Coroutines,您应该将 get() 的 return 值从 Call<VenuesMainResponse> 更改为 VenuesMainResponse。然后,您可以使用 try-catch 块来获取值,而不是在 Call.

上使用 enqueue

检查 this 答案以了解它,并随时询问这是否还不能解决问题:)

更新

好的,所以我刚刚注意到您似乎正在尝试使用 foursquare API。我最近用 foursquare API 在 Whosebug 上帮助了某人,所以我有点认得那些 Query 参数和你上面提供的代码中的 Venue 响应。

我还指导了此人如何使用 MVVM 架构从 Response 中获取 Venues。您可以在答案 .

中的 UPDATE 块之后找到获取响应的完整代码

我的这个答案包含代码,其中详细解释了 ViewModelRepositoryMainActivity 以及您需要的所有 Model 类从 foursquare API.

中获取 Venues

有不懂的可以私信我,我帮你解决! :)

回复:更新

所以这里是允许您将 代码与 Coroutines 一起使用的更改。

Repository.kt

class Repository {

    private val _data: MutableLiveData<mainResponse?> = MutableLiveData(null)
    val data: LiveData<mainResponse?> get() = _data

    suspend fun fetch(longlat: String, date: String) {

        val retrofit = Retro()
        val api = retrofit.retro.create(api::class.java)
   
        try {

            val response = api.get(
                longLat = longlat,
                date = date
            )
            _data.value = response
        } catch (e: Exception) {

            _data.value = null
        }
    }
}

ViewModel.kt

class ViewModel : ViewModel() {

    private val repository = Repository()

    val data: LiveData<mainResponse?> = repository.data

    fun getData(longLat: String, date: String) {

        viewModelScope.launch {

            repository.fetch(longLat, date)
        }
    }
}

api.kt

interface api {

    @GET("v2/venues/search")
    suspend fun get(
        @Query("ll") longLat: String,
        @Query("client_id") id: String = Const.clientId,
        @Query("client_secret") secret: String = Const.clientSecret,
        @Query("v") date: String
    ): mainResponse
}

MainActivity.kt

private val viewModel by viewModels<ViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

    viewModel.getData(
        longLat = "40.7,-74",
        date = "20210718" // date format is: YYYYMMDD
    )

    viewModel.data
        .observe(this, Observer {

            it?.let { res ->

                res.response.venues.forEach { venue ->

                    val name = venue.name

                    Log.d("name ",name)
                }
            }
        })    

    }
}