Android - Activity Persistency across reboots

     Android's approach to memory management required an ability to save application state as and when user pauses the application. In some cases, the state can't be truly restored like a persistent socket connection. The connection is lost upon a kill of the backgrounded application by low memory killer. Few applications request persistency via Manifest (android:persistent) but this works only for system applications and not third party applications.

    So third party applications have been limited via onSaveInstance and onRestoreInstanceState callbacks in Activity, Fragments etc. They would need to book keep if they had any active socket connections and restore them once they are hosted in a new process. This restore worked only as long as the device wasn't rebooted. The saved data was stored in-memory and didn't offer any way to restore after a device reboot. This had been the case for quite a few Android versions until recently where in the saved data is stored in a persistent storage. This enables the ability to restore applications after multiple reboots and this feature is controlled by a manifest attribute persistableMode, illustrated here.

    <!-- Define how an activity persist across reboots. Activities defined as "never" will not
         be persisted. Those defined as "always" will be persisted. Those defined as "taskOnly"
         will persist the root activity of the task only. See below for more detail as to
         what gets persisted. -->
    <attr name="persistableMode">
        <!-- The default. If this activity forms the root of a task then that task will be
             persisted across reboots but only the launching intent will be used. All
             activities above this activity in the task will not be persisted. In addition
             this activity will not be passed a PersistableBundle into which it could have
             stored its state. -->
        <enum name="persistRootOnly" value="0" />
        <!-- If this activity forms the root of a task then that task will not be persisted
             across reboots -->
        <enum name="persistNever" value="1" />
        <!-- If this activity forms the root of a task then the task and this activity will
             be persisted across reboots. If the activity above this activity is also
             tagged with the attribute <code>"persist"</code> then it will be persisted as well.
             And so on up the task stack until either an activity without the
             <code>persistableMode="persistAcrossReboots"</code> attribute or one that was launched
             with the flag Intent.FLAG_CLEAR_TASK_WHEN_RESET is encountered.

             <p>Activities that are declared with the persistAcrossReboots attribute will be
             provided with a PersistableBundle in onSavedInstanceState(), These activities may
             use this PeristableBundle to save their state. Then, following a reboot, that
             PersistableBundle will be provided back to the activity in its onCreate() method. -->
        <enum name="persistAcrossReboots" value="2" />

    </attr>


      Application developers can now control the persistency across reboots and create sockets etc if they have to upon a reboot. However, this attribute isn't documented despite being a public. It turns out that this feature is enabled by default for all applications without any additional work and isn't backward compatible. This is probably not documented as not many applications wouldn't want to be restored upon a reboot and having all applications being restored after a reboot is generally a good user experience.

No comments: