srisindhu saride
srisindhu saride

Reputation: 431

Android - kotlin.UninitializedPropertyAccessException: lateinit property homeActivityBinding has not been initialized

I have a BaseFragment class that is extended by all fragments in my app. And i have a HomeActivity class is a starting activity and also has some generic functionality in it.

Here is my HomeActivity code:

class HomeActivity : HomeActivityContract.View {

    private val presenter: HomeActivityContract.Presenter by inject {
        parametersOf(Schedulers.computation())
    }
    override val selectedWatchList: WatchlistItem
        get() = homeActivityBinding.watchlistSpinner.selectedWatchList
    override val watchlistItems: MutableList<WatchlistItem>
        get() = homeActivityBinding.watchlistSpinner.watchlistItems

    val bag = CompositeDisposable()
    lateinit var homeActivityBinding: ActivityHomeBinding

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


        if (presenter.hasAccount) {
            homeActivityBinding = ActivityHomeBinding.inflate(layoutInflater)
            setContentView(homeActivityBinding.root)
            Observables.combineLatest(
                realtimeDatabaseService.enableMaintenancePageForPhone,
                realtimeDatabaseService.maintenanceDate
            ) { isEnabled, _mMsg ->
                if (isEnabled) {
                    homeActivityBinding.homeMaintenanceView.root.visibility = View.VISIBLE
                    homeActivityBinding.homeParentView.visibility = View.GONE
                    homeActivityBinding.homeMaintenanceView.maintenanceTV.text = getString(R.string.maintenance_msg, _mMsg)
                } else {
                    homeActivityBinding.homeMaintenanceView.root.visibility = View.GONE
                    homeActivityBinding.homeParentView.visibility = View.VISIBLE

                    presenter.attachView(this)

                    presenter.dataProvider.getAccountUpdate()
                        .subscribeBy(onError = { it.printStackTrace() }, onNext = {
                            presenter.sendDeviceIdForCurrentAccount(isNotificationsEnabledInSettings)
                        }).disposeBy(lifecycle.disposers.onDestroy)

                    setSupportActionBar(homeActivityBinding.homeToolbar)
                
                    presenter.start()
                }
            }
                .subscribe()
                .disposeBy(lifecycle.disposers.onDestroy)
        } else {
            val intent = Intent(this, LoginActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
            }
            startActivity(intent)
            finish()
        }
    }

fun hideNavigationMenu() {
        homeActivityBinding.homeNavigationView.visibility = View.GONE /// This is where it says that homeActivityBinding is uninitialised.
    }

BaseFragment code:

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (isAdded)
            parentFragmentManager.let { fragmentManager ->
                takeIf { fragmentManager.backStackEntryCount >= 1 }?.let {
                        (activity as? HomeActivity)?.hideNavigationMenu()
                 }
            }
    }

So BaseFragment is calling hideNavigationMenu in HomeActivity. Here is the crash report:

Caused by kotlin.UninitializedPropertyAccessException: lateinit property homeActivityBinding has not been initialized
       at com.app.android.traderpro.etx.activities.homeActivity.HomeActivity.G5(HomeActivity.kt:7)
       at com.app.android.traderpro.etx.activities.homeActivity.HomeActivity.hideNavigationMenu(HomeActivity.kt:404)
       at com.app.android.traderpro.etx.fragments.BaseFragment.hideNavigationMenu(BaseFragment.kt:138)
       at com.app.android.traderpro.etx.fragments.BaseFragment.onCreate(BaseFragment.kt:153)
       at androidx.fragment.app.Fragment.performCreate(Fragment.java:3090)
       at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257)
       at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1424)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2968)
       at androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:2875)
       at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:252)
       at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:220)
       at com.app.android.traderpro.etx.activities.BaseActivity.onCreate(BaseActivity.kt:61)
       at com.app.android.traderpro.etx.activities.homeActivity.HomeActivity.onCreate(HomeActivity.kt:134)
       at android.app.Activity.performCreate(Activity.java:8207)
       at android.app.Activity.performCreate(Activity.java:8191)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3819)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4022)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:246)
       at android.app.ActivityThread.main(ActivityThread.java:8653)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

The first thing is I cannot replicate this crash and there are around 200 crashes reported in Firebase Crashlytics. And HomeActivity is the first activity that launches all other fragments. This crash is not happening as soon as this activity is started, it is happening after some time. So I don't understand how homeActivityBinding can be uninitialized.

I'd appreciate it if anyone can tell me how a lateinit property that is initialised can be uninitialized again

Upvotes: 0

Views: 152

Answers (1)

Tenfour04
Tenfour04

Reputation: 93834

Fragment.onCreate() is too early to be trying to access members of the Activity, even though it is already attached. From the onCreate() documentation:

Note that this can be called while the fragment's activity is still in the process of being created. As such, you can not rely on things like the activity's content view hierarchy being initialized at this point.

You should move your code from onCreate to onViewCreated.

Upvotes: 2

Related Questions