How to assign late initialize variable with secondary constructor in android fragment?

I am using Kotlin and fragments in my app. I created a secondary constructor to keep primary constructor empty in order to avoid the error of could not find fragment constructor. I assigned late initialize variable in secondary constructor of fragment but it is null when called, causing null pointer exception. Here is the code sequence:

class VideoFragment(
) : Fragment(),
VideoFileListener {

private lateinit var mainContext: Context
private lateinit var itemClickListener: ItemClickListener

constructor(
    mainContext: Context,
    itemClickListener: ItemClickListener
) : this() {
    this.mainContext = mainContext
    this.itemClickListener = itemClickListener
}
}

companion object {
    @JvmStatic
    fun newInstance(
        mainContext: Context,
        itemClickListener: ItemClickListener
    ) =
        VideoFragment(mainContext, itemClickListener)
}

I access my fragment with static newInstance function. Why these variables are not initialized in secondary constructor?

Answer

You kind of miss the point of the newInstance static method here. The whole point of that method is to put the given parameters supplied there into the fragment arguments, so the fragment can later retrieve those parameters from it’s arguments. This is necessary because on configuration change your Fragment will be recreated using the no-arg constructor, and then you’ll have someplace to restore the original arguments for your Fragment. Have a look at this answer for further explanation and example: https://stackoverflow.com/a/9245510/5601663

This has another effect. You can’t really have callbacks as Fragment arguments, because these arguments need to be Serializable or Parcelable. I highly recommend you watch this video from the point I linked, it elaborates further on this: https://youtu.be/dcYKW48tHQ4?t=1867

One last thing, if you got NullPointerException then it’s cause by something other then your lateinit property not being initialized, because that would produce an error similar to this: kotlin.UninitializedPropertyAccessException: lateinit property foo has not been initialized.