简体   繁体   中英

lateinit property providerFactory has not been initialized

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM