lateinit 属性 apiComponent 尚未在 Dagger 2 中初始化
lateinit property apiComponent has not been initialized in Dagger 2
我正在尝试在 recyclerview 中实施 Dragger 2,但在 运行 应用程序时出现以下错误:
kotlin.UninitializedPropertyAccessException: lateinit property apiComponent has not been initialized
at com.kabelash.squarerepos.MyRetroApplication$Companion.getApiComponent(MyRetroApplication.kt:18)
at com.kabelash.squarerepos.network.viewmodel.RetroViewModelFactory.create(RetroViewModelFactory.kt:21)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
at com.kabelash.squarerepos.network.view.RetroFragment.initViewModel(RetroFragment.kt:43)
at com.kabelash.squarerepos.network.view.RetroFragment.onCreate(RetroFragment.kt:29)
APIComponent.kt
@Singleton
@Component(modules = [AppModule::class, APIModule::class])
interface APIComponent {
fun inject(retrofitRepository: RetrofitRepository)
fun inject(retroViewModel: RetroViewModel)
fun inject(retroFragment: RetroFragment)
fun inject(retroViewModelFactory: RetroViewModelFactory)
}
NetworkActivity.kt
class NetworkActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.network_layout)
replaceFragment()
}
fun replaceFragment(){
supportFragmentManager
.beginTransaction()
.replace(R.id.container_retro_room, RetroFragment())
.commit()
}
}
RetroFragment.kt
class RetroFragment: Fragment() {
lateinit var retroViewModel: RetroViewModel
var fragmentView:View?=null
private var listAdapter: PostListAdapter?=null
private var postListLayoutBinding:PostListLayoutBinding?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initViewModel()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
postListLayoutBinding = DataBindingUtil.inflate(inflater, R.layout.post_list_layout,container,false)
fragmentView = postListLayoutBinding?.root
initAdapter()
setAdapter()
fetchRetroInfo()
return fragmentView
}
fun initViewModel(){
var retroViewModelFactory = RetroViewModelFactory()
retroViewModel = ViewModelProviders.of(this,retroViewModelFactory).get(RetroViewModel::class.java)
}
fun fetchRetroInfo(){
retroViewModel.postInfoLiveData?.observe(this,object:Observer<List<PostInfo>>{
override fun onChanged(t: List<PostInfo>?) {
t?.apply {
listAdapter?.setAdapterList(t)
}
}
})
}
private fun setAdapter(){
fragmentView?.post_list?.apply {
layoutManager = LinearLayoutManager(activity)
addItemDecoration(DividerItemDecoration(activity, DividerItemDecoration.VERTICAL))
adapter = listAdapter
}
}
private fun initAdapter(){
listAdapter = PostListAdapter(this@RetroFragment.requireActivity())
}
}
RetroViewModelFactory.kt
class RetroViewModelFactory : ViewModelProvider.Factory {
lateinit var apiComponent:APIComponent
@注入
lateinit var retrofitRepository: RetrofitRepository
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
// initDaggerComponent()
var apiComponent : APIComponent = MyRetroApplication.apiComponent
apiComponent.inject(this)
if (modelClass.isAssignableFrom(RetroViewModel::class.java)) {
return RetroViewModel(retrofitRepository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
fun initDaggerComponent(){
apiComponent = DaggerAPIComponent
.builder()
.aPIModule(APIModule(APIURL.BASE_URL))
.build()
apiComponent.inject(this)
}
}
有人可以帮助解决这个问题吗?我想不通。
如异常消息所述,您的 MyRetroApplication
class 中有一个名为 apiComponent
的 属性 标记为 lateinit
,尚未初始化. A lateinit
属性 如果您在设置它之前尝试读取它的值(例如此处,在工厂内),则会导致此异常。您应该在应用程序启动时在 MyRetroApplication
class 中创建一个 APIComponent
的实例,并将其分配给 属性.
我正在尝试在 recyclerview 中实施 Dragger 2,但在 运行 应用程序时出现以下错误:
kotlin.UninitializedPropertyAccessException: lateinit property apiComponent has not been initialized
at com.kabelash.squarerepos.MyRetroApplication$Companion.getApiComponent(MyRetroApplication.kt:18)
at com.kabelash.squarerepos.network.viewmodel.RetroViewModelFactory.create(RetroViewModelFactory.kt:21)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
at com.kabelash.squarerepos.network.view.RetroFragment.initViewModel(RetroFragment.kt:43)
at com.kabelash.squarerepos.network.view.RetroFragment.onCreate(RetroFragment.kt:29)
APIComponent.kt
@Singleton
@Component(modules = [AppModule::class, APIModule::class])
interface APIComponent {
fun inject(retrofitRepository: RetrofitRepository)
fun inject(retroViewModel: RetroViewModel)
fun inject(retroFragment: RetroFragment)
fun inject(retroViewModelFactory: RetroViewModelFactory)
}
NetworkActivity.kt class NetworkActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.network_layout)
replaceFragment()
}
fun replaceFragment(){
supportFragmentManager
.beginTransaction()
.replace(R.id.container_retro_room, RetroFragment())
.commit()
}
}
RetroFragment.kt
class RetroFragment: Fragment() {
lateinit var retroViewModel: RetroViewModel
var fragmentView:View?=null
private var listAdapter: PostListAdapter?=null
private var postListLayoutBinding:PostListLayoutBinding?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initViewModel()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
postListLayoutBinding = DataBindingUtil.inflate(inflater, R.layout.post_list_layout,container,false)
fragmentView = postListLayoutBinding?.root
initAdapter()
setAdapter()
fetchRetroInfo()
return fragmentView
}
fun initViewModel(){
var retroViewModelFactory = RetroViewModelFactory()
retroViewModel = ViewModelProviders.of(this,retroViewModelFactory).get(RetroViewModel::class.java)
}
fun fetchRetroInfo(){
retroViewModel.postInfoLiveData?.observe(this,object:Observer<List<PostInfo>>{
override fun onChanged(t: List<PostInfo>?) {
t?.apply {
listAdapter?.setAdapterList(t)
}
}
})
}
private fun setAdapter(){
fragmentView?.post_list?.apply {
layoutManager = LinearLayoutManager(activity)
addItemDecoration(DividerItemDecoration(activity, DividerItemDecoration.VERTICAL))
adapter = listAdapter
}
}
private fun initAdapter(){
listAdapter = PostListAdapter(this@RetroFragment.requireActivity())
}
}
RetroViewModelFactory.kt class RetroViewModelFactory : ViewModelProvider.Factory { lateinit var apiComponent:APIComponent @注入 lateinit var retrofitRepository: RetrofitRepository
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
// initDaggerComponent()
var apiComponent : APIComponent = MyRetroApplication.apiComponent
apiComponent.inject(this)
if (modelClass.isAssignableFrom(RetroViewModel::class.java)) {
return RetroViewModel(retrofitRepository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
fun initDaggerComponent(){
apiComponent = DaggerAPIComponent
.builder()
.aPIModule(APIModule(APIURL.BASE_URL))
.build()
apiComponent.inject(this)
}
}
有人可以帮助解决这个问题吗?我想不通。
如异常消息所述,您的 MyRetroApplication
class 中有一个名为 apiComponent
的 属性 标记为 lateinit
,尚未初始化. A lateinit
属性 如果您在设置它之前尝试读取它的值(例如此处,在工厂内),则会导致此异常。您应该在应用程序启动时在 MyRetroApplication
class 中创建一个 APIComponent
的实例,并将其分配给 属性.