Android App Startup Optimization
App startup speed is a key metric for user experience. Optimizing startup speed can significantly improve user retention.
Startup Types
1. Cold Start
- Definition: App starts completely from scratch
- Process: Create process → Initialize Application → Start main Activity → Layout loading → First frame draw
- Duration: Longest, needs optimization focus
2. Hot Start
- Definition: App switches from background to foreground
- Process: Directly resume Activity
- Duration: Shortest
3. Warm Start
- Definition: Between cold start and hot start
- Scenario: Process killed but Activity instance still retained by system
Startup Flow Analysis
shellCold start complete flow: Click Launcher Icon ↓ Zygote Fork App Process (about 100-200ms) ↓ ActivityThread.main() ↓ Application.attachBaseContext() ↓ Application.onCreate() ← Optimization focus ↓ Activity.onCreate() ↓ Activity.onStart() ↓ Activity.onResume() ↓ ViewRootImpl.performTraversals() ↓ First Frame Drawn ← Startup complete
Startup Optimization Strategies
1. Application Optimization
Lazy Initialization
kotlinclass MyApplication : Application() { override fun onCreate() { super.onCreate() // Avoid synchronous initialization on main thread // Use async or lazy initialization } }
Use ContentProvider for Lazy Init
kotlinclass InitProvider : ContentProvider() { override fun onCreate(): Boolean { // Initialize third-party SDKs return true } }
2. Async Initialization
kotlin// Use thread pool for async initialization val executor = Executors.newFixedThreadPool(4) executor.execute { // Initialize non-essential SDKs Bugly.init() PushService.init() }
3. Use Startup Library
kotlin// Define initialization task class WorkManagerInitializer : Initializer<WorkManager> { override fun create(context: Context): WorkManager { return WorkManager.getInstance(context) } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
4. Layout Optimization
Reduce Layout Hierarchy
xml<!-- Use ConstraintLayout to reduce nesting --> <androidx.constraintlayout.widget.ConstraintLayout> <!-- Flatten layout --> </androidx.constraintlayout.widget.ConstraintLayout>
Lazy Load Non-First-Screen Layout
kotlin// Use ViewStub viewStub.inflate()
Async Inflate
kotlin// Use AsyncLayoutInflater AsyncLayoutInflater(this).inflate(R.layout.activity_main, null) { view, _, _ -> setContentView(view) }
5. Class Loading Optimization
Dex Preloading
kotlin// Preload frequently used classes in Application Class.forName("com.example.MainActivity")
Avoid Reflection
- Reflection calls are time-consuming
- Use APT-generated code instead
6. Black/White Screen Optimization
Set Window Background
xml<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowFullscreen">true</item> </style>
Use Splash Screen (Android 12+)
xml<item name="android:windowSplashScreenBackground">@color/splash_background</item> <item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_icon</item>
Startup Time Measurement
1. System Logs
shelladb logcat -s ActivityManager | grep "Displayed" // Output: Displayed com.example/.MainActivity: +1s234ms
2. Systrace
shellpython systrace.py -a com.example -o trace.html
3. Code Timing
kotlinclass MyApplication : Application() { override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) Log.d("Startup", "attachBaseContext: ${System.currentTimeMillis()}") } }
Key Points
- Understand difference between cold start and hot start
- Master Application and Activity startup flow
- Familiar with async initialization and lazy loading strategies
- Understand Systrace and Profiler usage
- Master black/white screen optimization solutions