lateinit属性apiComponent尚未在Dagger 2中初始化

时间:2019-11-28 18:01:42

标签: android kotlin dependency-injection retrofit2 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 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)
}

}

有人可以帮助解决此问题吗?我不知道。

1 个答案:

答案 0 :(得分:0)

正如异常消息所述,您的apiComponent类中有一个名为lateinit的属性MyRetroApplication,尚未初始化。如果您尝试在设置之前读取lateinit属性的值(例如,在工厂内部),则会导致此异常。应用程序启动时,应在APIComponent类中创建MyRetroApplication的实例,并将其分配给该属性。