I'm using dagger 2 with kotlin in my project where i'm getting "UninitializedPropertyAccessException" in one of the fragments(Photos Fragment).
here is the code
class BaseApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.builder().application(this).build()
}
}
Application class
@Singleton
@Component(
modules = [
AppModule::class,
AndroidSupportInjectionModule::class,
ActivityBuildersModule::class
]
)
interface AppComponent : AndroidInjector<BaseApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
}
App Component class
@Module
interface ActivityBuildersModule {
@DashboardScope
@ContributesAndroidInjector(
modules = [
DashboardActivityModule::class,
DashboardViewModelsModule::class,
FragmentsBuilderModule::class
]
)
fun provideDashboardActivity(): DashboardActivity
}
Activity Builders module
@Module
class DashboardActivityModule {
@DashboardScope
@Provides
fun provideDashboardApi(retrofit: Retrofit): DashboardApi {
return retrofit.create(DashboardApi::class.java)
}
@DashboardScope
@Provides
fun provideAdapter(): PhotosRecyclerAdapter? {
return PhotosRecyclerAdapter()
}
}
Dashboard Activity
@Module
abstract class DashboardViewModelsModule {
@Binds
@IntoMap
@ViewModelKey(PhotosViewModel::class)
abstract fun bindAuthViewModel(photosViewModel: PhotosViewModel?): ViewModel?
}
ViewModelsModule
class ViewModelProviderFactory @Inject constructor(creators: Map<Class<out ViewModel>, Provider<ViewModel>>) : ViewModelProvider.Factory {
private val TAG = "ViewModelProviderFactor"
private var creators: Map<Class<out ViewModel>, Provider<ViewModel>> = creators
@NonNull
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
var creator: Provider<out ViewModel?>? = creators?.get(modelClass)
if (creator == null) { // if viewmodel has not been created
// loop through the allowable keys (aka allowed classes with the @ViewModelKey)
for ((key, value) in creators) { //if it's allowed, set the Provider<ViewModel>
if (modelClass.isAssignableFrom(key)) {
creator = value
break
}
}
}
//if this is not one of the allowed keys, throw exception
requireNotNull(creator) { "unknown model class : $modelClass" }
//return the provider
return try {
creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
Viewmodel provider
class PhotosFragment : Fragment() {
private val TAG = "PhotosFragment"
private var viewModel: PhotosViewModel? = null
@Inject
lateinit var providerFactory: ViewModelProviderFactory
@Inject
lateinit var adapter: PhotosRecyclerAdapter
//...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_item_list, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel = ViewModelProviders.of(this, providerFactory).get(PhotosViewModel::class.java)
}
//.....
}
I'm launching the fragment in Dashboard activity using navGraph
PS: https://github.com/venki131/PhotosAlbum
link for the same project.
please let me know how to fix this issue.
Your PhotosFragment should extend DaggerFragment, instead of just Fragment. Also, check if your activity extends DaggerAppCompatActivity, instead of just AppCompatActivity
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.