【问题标题】:Unable to invoke no-args constructor for retrofit2.Call MVVM Coroutines Retrofit无法为改造 2 调用无参数构造函数。调用 MVVM 协程改造
【发布时间】:2021-09-25 15:46:49
【问题描述】:

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

这是我的 apiclient 类:

class ApiClient {

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

这是我的端点类:

@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 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 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
    }

}

部分活动类:

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 数据类

data class VenuesMainResponse(
    val response: VenuesResponse
)

【问题讨论】:

    标签: android kotlin mvvm retrofit


    【解决方案1】:

    我认为no-args constructor警告应该和你的VenuesMainResponse有关,是data class吗?你也应该添加它的代码和完整的Log details

    另外,对于Coroutines,您应该将get() 的返回值从Call&lt;VenuesMainResponse&gt; 更改为VenuesMainResponse。然后,您可以使用try-catch 块来获取值,而不是在Call 上使用enqueue

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

    更新

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

    我指导该人如何使用MVVM 架构从Response 获取Venues。您可以在答案here 中找到UPDATE 块后获取响应的完整代码。

    我的这个答案有代码,详细解释了ViewModelRepositoryMainActivity,以及从foursquare API 获取Venues 所需的所有Model 类。

    如果你不明白,请告诉我,我会帮助你的! :)

    回复:更新

    因此,这里的更改将允许您将 this 代码与 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)
                    }
                }
            })    
    
        }
    }
    

    【讨论】:

    • 嗨 Mehul,我应该如何更改课程中的代码?
    • 我正在更新我的答案。
    • Yess Mehul 我看到了那个答案,但我想用 Coroutines 和那个代码,我想现在它在主线程上获取
    • 好的,我正在更新代码以将其与Coroutines 一起使用。一定要告诉它是否为您解决了问题。
    • 是的,很高兴听到这个消息:)
    猜你喜欢
    • 1970-01-01
    • 2015-08-02
    • 2019-05-07
    • 2020-02-14
    • 2022-12-05
    • 2018-06-02
    • 2011-10-08
    • 2017-12-20
    • 2019-08-24
    相关资源
    最近更新 更多