Search code examples
androidoopkotlinandroid-lifecycle

Where is the actual savedInstanceState object in lifecycle method onCreate()?


Where is the object savedInstanceState instantiated? Shouldn't it say somewhere, something like this val savedInstance = SavedInstanceState()?

MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
   }
}

Solution

  • It is instantiated by platform code. More specifically, the main system component responsible for keeping track of Activity states of apps is ActivityManagerService. This component forwards information about savedInstanceState to the appropriate application processes.

    Once the app process have this information, it runs local code to manage e.g. savedInstanceState. If you set a breakpoint in your onCreate() you can investigate the stack of calls that lead up to your onCreate() method. It is from that stack of calls that savedInstanceState originates. It can be different for different Android versions, but in my case on Android 10 that stack looks like this:

    onCreate:183, MainPagerActivity (com.mydomain.android.activity)
    performCreate:7802, Activity (android.app)
    performCreate:7791, Activity (android.app)
    callActivityOnCreate:1306, Instrumentation (android.app)
    performLaunchActivity:3245, ActivityThread (android.app)
    handleLaunchActivity:3409, ActivityThread (android.app)
    execute:83, LaunchActivityItem (android.app.servertransaction)
    executeCallbacks:135, TransactionExecutor (android.app.servertransaction)
    execute:95, TransactionExecutor (android.app.servertransaction)
    handleMessage:2016, ActivityThread$H (android.app)
    dispatchMessage:107, Handler (android.os)
    loop:214, Looper (android.os)
    main:7356, ActivityThread (android.app)
    invoke:-1, Method (java.lang.reflect)
    run:492, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
    main:930, ZygoteInit (com.android.internal.os)
    

    You can for example see that the code in the call chain is this (just move up the stack in the Android Studio debugger):

        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    

    and a bit further down:

                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
    

    where r.state is the savedInstanceState you are passed. ActivityClientRecord holds lots of state for an Activity.

    I could keep adding details to this mechanism, but hopefully it is enough to remove the "magic" of how you get a savedInstanceState.