Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Process Death Lab

A small Android learning app that shows where form state actually lives, and which of those stores survive:

  1. Recomposition
  2. Screen rotation
  3. Process death (task restored from Recents)
  4. A full restart after Force Stop

You fill in Name, Email, and Notes, then try to kill the UI in different ways. The State Inspector on the screen tells you whether the values came from the ViewModel, SavedStateHandle, or DataStore.

This is not a production form. It is a lab for Android lifecycle and state.

What the app is about

Android can throw away your UI without the user meaning to:

  • Compose recomposes (redraws) constantly.
  • Rotation destroys and recreates the Activity.
  • The system can kill the process to reclaim memory while the task stays in Recents.
  • The user can Force Stop or start a new task (Run from Android Studio, swipe away from Recents).

Those are different events. They need different stores.

Store Used for Survives Does not survive
remember UI chrome only (section open/closed) Recomposition Rotation, process death
ViewModel + StateFlow Live form on screen Recomposition, rotation Process death
SavedStateHandle Unsaved draft Process death if you return from Recents Force Stop, Run, swipe-away Recents
DataStore Permanent save Force Stop, new launch, reboot Nothing, until the user taps Save Permanently

Two ideas the app keeps separate on purpose:

  • Unsaved draft — every keystroke goes to the ViewModel and SavedStateHandle. Not to disk.
  • Permanent form — written only when you tap Save Permanently. That is DataStore.

Clear Form clears the draft only. DataStore still has the last permanent save. Close the app fully and reopen: the saved form comes back.

Simulate Process Death cannot kill the process the way Android does. It flushes the draft and points you at Test 3. Use Logcat Terminate Application or adb shell am kill for a real kill.

Architecture

FormScreen (Compose, stateless)
    ↓ events up, FormUiState down
FormViewModel (StateFlow + SavedStateHandle)
    ↓ only on Save Permanently / launch restore
FormRepository
    ↓
FormDataStore (Preferences DataStore)

The screen never talks to DataStore. The ViewModel never talks to the file API directly.

How to test

Build and run the app module on a device or emulator (com.processdeath.app). After each test, read the State Inspector at the bottom of the screen.

The same steps are inside the app under How to Test.

Test 1: Recomposition

Goal: Prove the form does not live in the composition.

  1. Type a name.
  2. Expand or collapse How It Works / How to Test (that redraws UI).
  3. The form text should still be there.

Why it survives: The form is in the ViewModel StateFlow, outside Compose. Redrawing the UI does not recreate the ViewModel.

remember would also survive recomposition, but this app does not store Name / Email / Notes there. Those flags are only “is this section open?”

Test 2: Screen Rotation

Goal: Prove ViewModel outlives the Activity.

  1. Enter data.
  2. Rotate the device (or enable rotation in the emulator).
  3. The form should still be there.
  4. How It Works / How to Test will likely close.

Why the form survives: The Activity is destroyed and recreated. The ViewModelStore is kept, so the new Activity gets the same ViewModel.

Why the sections close: Their expand state is remember. That dies with the composition.

Test 3: Process death (unsaved draft)

Goal: Prove SavedStateHandle can restore a draft after the process is gone.

  1. Enter data. Do not tap Save Permanently.
  2. Press Home (leave the task in Recents).
  3. Kill the process without finishing the task:
    • Android Studio LogcatTerminate Application, or
    • adb shell am kill com.processdeath.app
  4. Open the app from Recents, not Run, not the launcher if that starts a new task.

Verify: Fields come back. Inspector says this session loaded from SavedStateHandle.

Limits of SavedStateHandle:

  • Small data only (strings, ints, parcels). Not a database.
  • Restored only if Android still has the task.
  • Force Stop, Run from Android Studio, and swipe away from Recents start a new task. The draft is gone.

Do not use this button as a real kill. An app cannot reliably simulate system process death by calling killProcess on itself.

Test 4: Permanent save

Goal: Prove DataStore is the “I meant to keep this” path.

  1. Enter data.
  2. Tap Save Permanently. You should see the saved message.
  3. Force Stop the app (Settings → Apps → Process Death Lab → Force Stop), or press Run again in Android Studio.
  4. Open the app from the launcher.

Verify: Fields come back. Inspector says this session loaded from DataStore.

Why DataStore: You asked to persist the form. That belongs on disk, not in a task-scoped bundle. Preferences DataStore is a file API for a few key-value fields. Room would be for a table of rows.

Compare Test 3 and Test 4

Action Skip Save, then kill Save, then Force Stop
Recents restore after am kill Draft from SavedStateHandle Same values, but source was disk if it was a new task
Force Stop / Run / new task Empty, or last permanent save if you had one Form from DataStore

Project structure

com.processdeath.app
├── MainActivity.kt          Hosts ViewModel, collects StateFlow
├── ui
│   ├── FormScreen.kt        Stateless UI + inspector + test guide
│   ├── FormViewModel.kt     Draft + restore rules
│   └── FormUiState.kt       Immutable snapshot
└── data
    ├── FormRepository.kt    ViewModel → disk boundary
    └── FormDataStore.kt     Preferences DataStore

Requirements

  • Android Studio with the project SDK
  • minSdk 24
  • Kotlin + Jetpack Compose + Material 3

About

Android lab for form state across rotation and process death.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages