App lifecycle
Skill almasumdev/awesome-mobile-agent-skills/.github/skills/lifecycle/app-lifecycle
Stack-agnostic agent skills and workflows shared across iOS, Android, Flutter, React Native, and KMP.
npx -y skills add almasumdev/awesome-mobile-agent-skills --skill app-lifecycleAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Mobile app lifecycle across iOS and Android (foreground, background, suspended, killed), state restoration, process death, and cross-platform parallels in Flutter and React Native. Use when handling background work, persistence of in-flight state, or resume flows.
SKILL.md
6.7 KB, as published. Nobody here has run it
App Lifecycle
Instructions
Mobile apps run in a hostile runtime. The OS freezes, backgrounds, and kills processes to preserve battery and memory. Treating the lifecycle as an afterthought leads to lost data, broken deep links, and angry reviews.
1. The Lifecycle States
Both platforms converge to roughly:
| State | iOS term | Android term | Cross-platform term |
|---|---|---|---|
| Visible & interactive | Active | Resumed | Foreground |
| Visible but not active | Inactive (incoming call, control center) | Paused | Inactive |
| Not visible | Background | Stopped | Background |
| Frozen but in memory | Suspended | Stopped | Suspended |
| Gone | Terminated | Process death | Killed |
2. Transitions and Contracts
- Entering background: cancel network calls not needed offline, persist drafts, release camera/audio/sensors, pause timers.
- Entering foreground: refresh data that may be stale, reconnect websockets, re-check auth, reclaim resources.
- Process death: on cold start, detect whether this is a restart from death (saved-state bundle present) or a first launch; restore the previous screen and selection.
- Low memory warning: drop caches, close non-visible images, release heavy objects.
3. Platform Hooks
// Swift / SwiftUI
@main struct App: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup { RootView() }
.onChange(of: scenePhase) { _, phase in
switch phase {
case .active: AppEvents.foreground()
case .inactive: AppEvents.inactive()
case .background: AppEvents.background()
@unknown default: break
}
}
}
}
// Kotlin / Android (Lifecycle-aware observer)
class AppLifecycleObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) = AppEvents.foreground()
override fun onStop(owner: LifecycleOwner) = AppEvents.background()
}
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
// Flutter
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); }
@override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); }
@override void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed: AppEvents.foreground();
case AppLifecycleState.inactive: AppEvents.inactive();
case AppLifecycleState.paused: AppEvents.background();
case AppLifecycleState.detached: AppEvents.detached();
case AppLifecycleState.hidden: break;
}
}
}
// React Native
import { AppState } from 'react-native';
useEffect(() => {
const sub = AppState.addEventListener('change', (s) => {
if (s === 'active') AppEvents.foreground();
else if (s === 'background') AppEvents.background();
});
return () => sub.remove();
}, []);
4. State Restoration
State restoration keeps the user's mental context after the OS kills the process.
- iOS:
@SceneStorage,StateRestorationwithNSUserActivityfor deep links. - Android:
SavedStateHandlein ViewModels;onSaveInstanceStatefor Views; Navigation Component restores the back stack. - Flutter:
RestorationMixin,RestorableProperty,restorationScopeIdinMaterialApp. - React Native:
@react-navigationpersistence withAsyncStorage.
Keep restored state small (IDs, not payloads). Refetch the data using the ID on resume.
5. Background Work Budgets
The OS is strict. Do not run background network or CPU work without a matching API:
- iOS:
BGTaskScheduler(background refresh, processing tasks),URLSessionbackground configuration for downloads, VoIP push for real-time. - Android:
WorkManagerfor deferrable guaranteed work,ForegroundServicefor user-visible ongoing work (with the right foreground-service type declared),JobSchedulerunder the hood. - Flutter:
workmanagerplugin, native channel on iOS. - React Native:
expo-background-fetch,react-native-background-fetch, Headless JS on Android.
Assume background execution may never happen. Design for eventual consistency and sync on foreground.
6. Process Death and Cold Start
- Restore navigation first, then restore feature state.
- Re-run auth checks and token refresh on every cold start.
- If a push notification launched the app, route to the target screen only after auth is verified.
- Measure cold start time; store and foreground launches should be under 2 seconds to first meaningful paint.
7. Common Bugs
- Losing form drafts when the user switches apps. Fix: persist on
onPause/background. - Continuing location updates when backgrounded without user awareness. Fix: stop on background unless there is a declared background mode and a UI affordance.
- Showing stale data after a long background. Fix: soft-invalidate caches on foreground and refetch.
- Keeping websockets open while backgrounded. Fix: close on background, reconnect with backoff on foreground, and rely on push for real-time.
- Deep link opens on cold start before the nav graph is ready. Fix: buffer intents until the navigator is mounted.
8. Observability
Log these events (without PII):
app.foreground,app.background,app.cold_start,app.warm_start.restore.success/restore.failurewith a bucketed reason.- Cold-start duration and first-frame-time as metrics, not logs.
9. Anti-Patterns
- Running long work in
onPauseorapplicationWillResignActive. You have milliseconds. - Storing large objects in saved-state bundles. Store IDs, rehydrate.
- Polling while backgrounded. Use push or periodic
WorkManager/BGTask. - Assuming the app was foreground since last launch. Always check.
Checklist
- Foreground/background transitions have explicit handlers.
- Drafts and in-flight forms persist on background.
- State restoration stores small keys and rehydrates data.
- Background work uses the platform-sanctioned API with correct declarations.
- Cold-start routing waits for auth and navigator readiness.
- Websockets and media resources are released on background.
- Cold-start and warm-start times are measured and budgeted.
- App handles low-memory warnings by dropping caches.