Testing Rotation, App Switching and Process Death in a Google Play Closed Test

Some of the most annoying bugs in a new Android app only show up when the system interrupts it. A tester fills in half a form, switches to a messaging app for two minutes, comes back, and finds your app on the start screen with everything gone. You never saw it because on your dev phone the app stayed in memory the whole time.
This post covers how to test that class of bug before and during your closed test: configuration changes (rotation, dark mode, font size, language) and process death (Android killing your app while it sits in the background). Both are easy to reproduce once you know how, and both are good things to ask testers about.
Two different things that look similar to users
Testers will not tell you which one they hit. They will say "it lost my data" or "it went back to the beginning". You need to know the difference to fix it.
Configuration changes
When the screen rotates, the user switches between light and dark theme, changes font size, or changes the system language, Android may recreate your activity by default. The process stays alive. State held only in the activity's fields is lost, but a ViewModel survives.
Process death
When your app is in the background and the device needs memory, Android can kill the whole process. When the user returns, the system recreates your activity from the saved instance state, but everything in memory, including your ViewModel, singletons and in-memory caches, is gone. Whether and when this happens depends on the device, its RAM and what else the user is running. That is exactly why real phones find bugs your emulator does not.
The official guide to saving UI state is at developer.android.com. It is worth reading if you have never handled process death on purpose.
Reproduce it yourself first
Do this before uploading a build. It takes about fifteen minutes and catches the obvious cases.
- Turn on "Don't keep activities" in Developer options. Every time you leave a screen, the system destroys it. Use your app normally and watch for lost input, blank screens or crashes on return. Turn it off afterwards so you do not blame your app for everything else.
- Kill the process while the app is backgrounded. Put the app in the background with the Home button, then run
adb shell am kill your.package.name. This only kills a process that is safe to kill, which is why it has to be backgrounded first. Reopen the app from the recents screen and see what comes back. - Rotate on every screen, even if you think the app is portrait only. Check your manifest and any orientation lock you set in code.
- Toggle dark mode, font size and language while the app is open on a key screen.
Reopening from recents is the important part. It is the path where Android restores your task, and it behaves differently from tapping the launcher icon, which starts fresh.
Flows most likely to break
Not every screen needs the same attention. Focus on places where the user leaves your app on purpose and expects to return to the same spot:
- Long forms and onboarding. Anything with several fields or steps. Does half-typed text survive? Does the step counter?
- Camera, gallery and file pickers. The system picker is a different app. Your process can be killed while it is open, and the result then arrives in a recreated activity.
- Permission dialogs and the Settings detour. If a user goes to system Settings to grant a permission, your app may be killed while they are there. See also the post on testing runtime permissions in a closed test.
- Sign-in through a browser or another app. Redirect-based login returns to your app after a detour. If you hold login state only in memory, it can vanish in the middle.
- Payment or checkout steps. Losing a cart or showing a confusing state after returning is a bad first impression.
- Timers, playback and active sessions. A workout timer or audio player needs a clear policy about what happens when the app is backgrounded for ten minutes.
What to save, and where
A simple rule of thumb helps:
- Small, transient UI state (selected tab, text in a field, scroll position, current step) belongs in saved instance state, for example through
SavedStateHandlein aViewModelorrememberSaveablein Compose. It survives both configuration changes and process death. - In-memory-only state in a ViewModel survives rotation but not process death. That is fine for data you can reload, and not fine for something the user typed.
- Real user data (a draft, a completed entry, a setting) should be written to persistent storage as soon as it matters, not when the screen closes.
Avoid putting large objects in saved state. It is meant for small values, and oversized bundles cause their own problems. Save identifiers and reload the data.
One more habit: do not try to fix rotation bugs by blocking rotation or by declaring that your activity handles every configuration change itself, unless you really handle them. That hides the symptom for one case and leaves process death untouched.
Using the closed test to find what you missed
The closed test is a good chance to see this on hardware you do not own. Testers use their own phones with their own apps installed, so memory pressure is real. If you use a service like TesterMob, where testers use each app for about 20 minutes a day on their own Android phones and send written feedback, you get a natural mix of devices and habits. Testers who have messaging apps and a browser open in the background will trigger process death more often than your clean test phone.
You do not need testers to do anything technical. Add a short, plain task to your test instructions:
Once during the test, start a task in the app (fill in a form or begin a new entry), leave the app for a few minutes to use another app, then come back. Tell us what you saw: was your progress still there, did the app restart from the beginning, or did it crash? Please also mention your phone model and Android version.
Add a second task: rotate the phone on two or three screens, and switch between dark and light theme once. Ask for a sentence on anything that looked broken, cut off or reset.
Reading the reports
Tester descriptions map to causes roughly like this:
- "It went back to the start screen": usually process death with navigation state not restored, or a launcher-start path being used instead of restoring the task.
- "My text disappeared": input held in a field or in-memory object only. Check rotation first, since it is the quickest to reproduce.
- "The screen was blank": often a screen that expects data from a previous screen or singleton that no longer exists after the process was recreated.
- "The app crashed when I came back": look in Play Console's crash reports for a
NullPointerExceptionorlateiniterror on a screen reached from the background. See the post on handling crashes reported during a closed test.
If you added the optional TesterMob Android SDK, the daily activity in your dashboard can help you check whether a tester actually opened the app on the day they reported an issue, which gives you context when a report is vague. It does not replace reproducing the bug yourself with the steps above.
A short checklist
- Test every main screen with "Don't keep activities" on.
- Background the app, run
am kill, reopen from recents. - Rotate, change theme, font size and language on key screens.
- Check picker, permission, login and checkout round trips.
- Persist anything the user would be upset to lose.
- Ask testers for one background-and-return task, and collect device model and Android version.
Fixing these issues makes your app feel solid, and it gives you real changes to put in your next update. Keep in mind that Google Play requirements can change, so check Play Console Help for the current closed testing rules, and note that no testing approach, including ours, can guarantee production approval. If you want real testers on real phones for your test, see how TesterMob works for developers, the pricing page ($9.99 per app, paid once), or the FAQ.