【问题标题】:error: [Dagger/MissingBinding] java.lang.Integer cannot be provided without an @Inject constructor or an @Provides-annotated method错误:[Dagger/MissingBinding] java.lang.Integer 不能在没有@Inject 构造函数或@Provides-annotated 方法的情况下提供
【发布时间】:2021-09-22 10:19:06
【问题描述】:

我正在开发一个 Retrofit 2 kotlin 应用程序,一切都很好,直到我尝试实现另一个功能,让用户通过 id 过滤到不同用户的 API。

应用程序的第一种工作方式是调用所有用户,并在我的 ViewModel 的 onClick 侦听器中恢复其中一个,并显示在屏幕上。

所以,我尝试做同样的事情,但我添加了一个 EditText 让用户按 id 过滤,当我实现该功能时,我开始收到以下错误:

error: [Dagger/MissingBinding] java.lang.Integer cannot be provided without an @Inject constructor or an @Provides-annotated method.

所以,我的 kotlin 类如下:

MainActivity.kt

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var Etid: EditText
    private lateinit var id: Number
    private val quoteViewModel: QuoteViewModel by viewModels()
    private var userSearch: QuoteModel = TODO()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //Pasa el layout a linkear con el binding.
        binding = ActivityMainBinding.inflate(layoutInflater)

        //settemos la vista
        setContentView(binding.root)

        //Inicilizamos el controlador UI-data (ViewModel)
        quoteViewModel.onCreate()

        //Inicilizamos el EditText.
        Etid.findViewById(R.id.EtId) as EditText

        //Establecemos un observer en los datos
        quoteViewModel.quoteModel.observe(this, Observer {
            binding.tvName.text = it.name
            binding.tvEmail.text = it.email
            binding.tvAddress.text = it.addrees
            binding.tvPhone.text = it.phone
            binding.tvWebsite.text = it.website
            binding.tvCompany.text = it.company
        })
        //Establecemos un observer en la carga de la página.
        quoteViewModel.isLoading.observe(this, Observer {
            binding.loading.isVisible = it
        })




        binding.viewContainer.setOnClickListener {
            id = Etid.id;
            userSearch = quoteViewModel.getUserIdQuote(id as Int) as QuoteModel
            it.findViewById<TextView>(R.id.tvName).text = userSearch.name
            it.findViewById<TextView>(R.id.tvAddress).text  = userSearch.addrees
            it.findViewById<TextView>(R.id.tvCompany).text = userSearch.company
            it.findViewById<TextView>(R.id.tvEmail).text = userSearch.email
            it.findViewById<TextView>(R.id.tvPhone).text = userSearch.phone
            it.findViewById<TextView>(R.id.tvWebsite).text = userSearch.website
        }

    }

}

关于我的改造配置:

NetworkModule.kt


@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

    @Singleton
    @Provides
    fun provideRetrofit():Retrofit{
        return Retrofit.Builder()
            .baseUrl("https://jsonplaceholder.typicode.com/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    @Singleton
    @Provides
    fun provideQuoteApiClient(retrofit: Retrofit):QuoteApiClient{
        return retrofit.create(QuoteApiClient::class.java)
    }
}

我的数据模型如下:

data class QuoteModel(
@SerializedName("id") val quote: Number,
@SerializedName("name") val name: String,
@SerializedName("email") val email: String,
@SerializedName("address") val addrees: String,
@SerializedName("phone") val phone: String,
@SerializedName("website") val website: String,
@SerializedName("company") val company: String,
)`

我的提供者服务和存储库是:

QuoteProvider.kt

    @Singleton
class QuoteProvider @Inject constructor() {
    var allUsers: List<QuoteModel> = emptyList1()
    var userById: QuoteModel = listOf<QuoteModel>() as QuoteModel

}
`

QuoteService.kt

    class QuoteService @Inject constructor(private val api:QuoteApiClient) {

    suspend fun getAllUsers(): List<QuoteModel> {
        return withContext(Dispatchers.IO) {
            val response = api.getAllUUsers()
            response.body() ?: emptyList1()
        }
    }

    suspend fun getUserById(id:Number): QuoteModel{
        return withContext(Dispatchers.IO){
            val response = api.getUserById(id)
            response.body() ?: listOf<QuoteModel>()
        } as QuoteModel
    }
}

QuoteRepository.kt

    class QuoteRepository @Inject constructor(
    private val api: QuoteService,
    private val quoteProvider: QuoteProvider
) {

    suspend fun getAllUsers(): List<QuoteModel> {
        //extraemos los users de la api
        val response = api.getAllUsers()
            //Le pasamos el [] de users al repository de la app.
        quoteProvider.allUsers = response
        return response
    }

    suspend fun getUserById(id: Number): QuoteModel {
        //Recogemos el usuario pasandole el Id al QueryRepository
        val response = api.getUserById(id)
        quoteProvider.userById = response

        return response
    }
}

最后我通过twot clases控制了对repository的调用,不知道是不是这样用的。

class GetUserById @Inject constructor(private val repository: QuoteRepository, private var id: Int) {

//TODO() Si no funciona probar a sacarlo del repository.
suspend  operator fun invoke(id: kotlin.Int): QuoteModel {
    //val id = id
    return repository.getUserById(id)
}

}

class GetAllUsers @Inject constructor(private val repository: QuoteRepository) {
    suspend operator fun invoke() = repository.getAllUsers()

}

也许错误可能在实现的结构中,而不是某些类的错误代码

希望您对改造的使用有一定的了解,可以提供帮助。

如果是这样,请提前感谢!

【问题讨论】:

  • GetUserById 构造函数中删除 private var id: Int
  • 还有listOf&lt;QuoteModel&gt;() as QuoteModel看起来很奇怪,会导致ClassCastException
  • 你是对的。你的建议解决了我的问题,但知道我在你提到的那一行中得到了 ClassCastException。我可以实例化一个空的 QuoteModel,就像使用 emptyList()
  • idk "empty QuoteModel" 是什么意思,如果没有对象,您可以返回null,或者您可以使用空字段创建实例QuoteModel(0, "", ...)

标签: android kotlin retrofit2


【解决方案1】:

我认为你必须提供quoteserviceclass

@Singleton
class QuoteService @Inject constructor(private val api:QuoteApiClient) {
    suspend fun getAllUsers(): List<QuoteModel> {
        return withContext(Dispatchers.IO) {
            val response = api.getAllUUsers()
            response.body() ?: emptyList1()
        }
    }

    suspend fun getUserById(id:Number): QuoteModel{
        return withContext(Dispatchers.IO){
            val response = api.getUserById(id)
            response.body() ?: listOf<QuoteModel>()
        } as QuoteModel
    }
}

编辑: 对不起,我的意思是添加单例注释不提供

【讨论】:

  • 那我应该如何实现呢?
  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • 我已经编辑了我的答案,只需将@singleton 添加到上面的类名中,如果我穿坏了,对不起
  • 好吧,您的建议解决了最初的问题,但现在我收到以下错误:com.google.gson..JsonSyntaxException: java.lang:illegalStateException: Expected a string but was BEGIN_OBJECT
  • 你能给我一个细节吗?,字符串但是是开始对象是因为你的数据类型和错误说的不一样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-06
  • 2021-05-05
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多