Search code examples
androidkotlinnullfragmentcompanion-object

Kotlin Companion Object is null when referenced


Not sure if I am using this companion object properly.

Data class:

data class AppModel(
    val name: String,
    val items: List<ItemModel>,
)

Set the data:

open class PathManager() {

    companion object {
        var shared = PathManager()    // SHARED OBJECT IN QUESTION
    }

    var app: AppModel? = null

    fun setUp() {
        // Show loading...

        // Parse the JSON
        val gson = GsonBuilder().create()
        val text = mainActivity.resources.openRawResource(R.raw.jsonFile)  
            .bufferedReader().use { it.readText() }
        val appModel = gson.fromJson(text, AppModel::class.java)

        app = appModel

        performInitialPath()
    } 

    private fun performInitialPath() {

        val app = app?.let { it } ?: error("Attempted to start without an App Config.")

        this.app = app    // DEBUGGER SHOWS CORRECT VALUES HERE

        // Removed irrelevant code for readability, builds 'initialFoo' here

        this.mainActivity.addFragment(initialFoo)
    }
}

Fragment Builder Class (looks for Path Manager companion object here):

class Frag : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        var itemModels: List<ItemModel>? = null

        if(PathManager.shared.app?.items != null) {  // NULL - WHY?
            itemModels = PathManager.shared.app?.items  
        }
   }
}

To sum up what happens:

  1. AppModel is built properly in PathManager(). The data IS there (can see in debugger)

  2. Path Manager launches 'Frag()' class

  3. Frag() class references back to the companion object created in PathManager(), attempting to find data in 'PathManager.shared.app?.items', but the data in there is null, when it should not be. Isn't a companion object the same as a Static variable?

I am certain I'm missing something, just looking for advice. Am I calling the companion object correctly? Can I not reference it from a new class like this? What gives?


Solution

  • PathManager.shared.app?.items is always null because you are never assigning the AppModel to companion object. var app: AppModel? = null instance in PathManager class and PathManager.shared.app are two different objects.

    To store the static data, you can do something as below:

    open class PathManager() {
    
        companion object {
            //Here Don't create object is you dont need it 
            //var shared = PathManager()    // SHARED OBJECT IN QUESTION
    
            //Create AppModel instance.
            var mAppModel: AppModel? = null
        }
    
        //Comment this as will manage companion object.
        //var app: AppModel? = null
    
        fun setUp() {
            // Show loading...
    
            // Parse the JSON
            val gson = GsonBuilder().create()
            val text = mainActivity.resources.openRawResource(R.raw.jsonFile)  
                .bufferedReader().use { it.readText() }
            val appModel = gson.fromJson(text, AppModel::class.java)
    
            mAppModel = appModel
    
            performInitialPath()
        } 
    
        private fun performInitialPath() {
    
            val app = app?.let { it } ?: error("Attempted to start without an App Config.")
    
            mAppModel = app    // DEBUGGER SHOWS CORRECT VALUES HERE
    
            // Removed irrelevant code for readability, builds 'initialFoo' here
    
            this.mainActivity.addFragment(initialFoo)
        }
    }
    

    And to use this in other class

    class Frag : Fragment() {
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    
            var itemModels: List<ItemModel>? = null
            //Retrive the list from shared object.
            if(PathManager.mAppModel?.items != null) {  // NULL - WHY?
                itemModels = PathManager.mAppModel?.items  
            }
       }
    }