https://kotlinlang.org logo
#android
Title
# android
e

Ellen Spertus

03/09/2020, 6:48 PM
I’m trying to understand how companion objects lifetimes interact with the Android lifecycle. I have an app that includes something like this:
Copy code
class MainActivity {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Metadata.initialize()
    }
}

class Metadata {
    companion object {
        boolean initialized = false

        fun initialize(context: Context) {
            check(!initialized)
            // do stuff (omitted)
            initialized = true
        }
    }
}
Sometimes my app fails because the
check
at the beginning of
Metadata.initalize()
fails, which implies that the companion object is surviving the destruction of
MainActivity
, despite their presumably being in the same process. Could someone help me understand why the companion object stays around even if the activity needs to be re-created?
c

Casey Brooks

03/09/2020, 6:54 PM
Companion objects are analogous to
static
fields in Java. They stick around for the entire application lifetime, not for the lifetime of an Activity instance.
1
z

Zach Klippenstein (he/him) [MOD]

03/09/2020, 6:54 PM
An Android process doesn’t die when an activity is destroyed, or even when all activities in the process are destroyed. The OS will “cache” processes when possible to decrease startup time if the user returns to an app.
1
👆 2
e

Ellen Spertus

03/09/2020, 6:56 PM
Thanks! The Android documentation says: “The system never kills an activity directly to free up memory. Instead, it kills the process in which the activity runs, destroying not only the activity but everything else running in the process, as well.” https://developer.android.com/guide/components/activities/activity-lifecycle#asem
👍 1
Would the best practice be to make this change:
Copy code
fun initialize(context: Context) {
    if (!initialized) {
        // do stuff (omitted)
        initialized = true
    }
}
c

Casey Brooks

03/09/2020, 6:58 PM
You should probably avoid having companion objects be tied to application/activity lifecycles in any way. Use ViewModels for managing data that requires explicit initialization/cleanup in response to the app lifecycle
2
e

Ellen Spertus

03/09/2020, 7:00 PM
Gotcha, @Casey Brooks. I was planning to switch to from companion objects anyways for other reasons (including testability).
@Zach Klippenstein (he/him) [MOD] Do you know anywhere the behavior you describe is documented so I can understand it better?
c

Casey Brooks

03/09/2020, 7:05 PM
@Ellen Spertus This article describes the memory model of Android apps, and the behavior mentioned above is described in the last section https://developer.android.com/topic/performance/memory-overview#SwitchingApps
🥇 1
e

Ellen Spertus

03/09/2020, 7:06 PM
I often wish that Android programming weren’t so complicated, but at least we get to program in Kotlin, so that’s a consolation.
c

codeslubber

03/09/2020, 7:28 PM
a lot of the complexity is just a function of not great initial design, the improvements that came from the ViewModel stuff illustrate that, just the torture of orientation changes was so much unneeded suffering cast on thousands of people..
👍 2
6 Views