ahjo4321hsotuhsa
ahjo4321hsotuhsa

Reputation: 430

UninitializedPropertyAccessException: lateinit property binding has not been initialized

I am getting a random crash "lateinit property binding has not been initialized". Most of the time it's working fine but a few time randomly we are getting this crash on crashlytics.

Please let me know what's wrong here

I have a BaseActivity with following code

abstract class BaseActivity<D : ViewDataBinding> : AppComptActivity() {
    abstract val layoutId: Int
    lateinit val binding: D
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState:Bundle)
        binding = DataBindingUtil.setContentView(this, layoutId)
        ....

    }
}

I have a HomeActivity which override BaseActivity with following code

class HomeActivity : BaseActivity<ActivityHomeBinding>() {

    override val layoutId: Int get() = R.layout.activity_home

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState:Bundle)
        ....

    }
}

I am using bottomNavigation menu and one of the fragment is HomeFragment

class HomeFragment : BaseFragment<FragmenntHomeBinding>() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState:Bundle)
        (activity as HomeActivity).binding.appBarHome.visible(false)
        //HERE I AM GETTING  lateinit property binding has not been initialized crash
    }
}

I don't want to use isInitialized property of lateinit as this will not solve my issue

Upvotes: 0

Views: 262

Answers (2)

David Wasser
David Wasser

Reputation: 95626

If you have an orientation change or other config change, or the OS process is killed while in the background and the user returns to the app, Android will recreate the Activity and the Fragments.

Unfortunately, it creates the Fragments first, before creating the Activity. So you cannot rely on the existence of the Activity until the Fragment has been attached to the Activity. You should move code that relies on the existence of the Activity to onActivityCreated().


Note: I also agree with the comment about not doing it this way. Your Fragment should not make assumptions like this (that it is hosted by HomeActivity), but instead should make some callback to the hosting Activity and let the hosting Activity set the visibility of the app bar (or whatever else it wants to do).

Upvotes: 1

Luk&#225;š Anda
Luk&#225;š Anda

Reputation: 590

As mentioned in the comment, I'd suggest instead of calling parent container (Activity) objects directly, register a listener to a navigation change like this in HomeActivity:

navController.addOnDestinationChangedListener { controller, destination, arguments ->
    if(destination.id = R.id.homeFragment) {
        // TODO hide/show your view here
    }
}

In that case, you are sure that the view gets hidden/shown when it should be without relying on the HomeFragment being only in HomeActivity as this can change in the future and your app will start crashing

Upvotes: 1

Related Questions