深入浅出安卓冷启动/热启动优化

341 阅读3分钟

深入浅出安卓冷启动/热启动优化

一、启动类型分清楚

1. 冷启动(最慢)

👉 场景:第一次打开App或被杀后重启
👉 比喻:新店开张,要装修+招人+备货
👉 耗时:1.5秒以上用户就能感觉到

2. 温启动(中等)

👉 场景:App还在后台但Activity被回收
👉 比喻:餐厅还在营业,但要重新摆桌子
👉 耗时:通常1秒左右

3. 热启动(最快)

👉 场景:App完全在后台(比如按Home键退出)
👉 比喻:菜品已经做好,直接端上来
👉 耗时:理想情况0.5秒内

二、冷启动优化六大招

大招1:Application减肥

常见问题

public class MyApp extends Application {
    @Override
    public void onCreate() {
        // 一堆第三方库初始化
        PushSDK.init(this);  // 推送
        Analytics.init(this); // 统计
        Database.init(this); // 数据库
        // ...还有10个库
    }
}

优化方案

  1. 懒加载(用的时候再初始化)
    class PushLazyLoader {
        static void init(Context ctx) {
            // 首次调用推送时初始化
        }
    }
    
  2. 后台线程加载
    new Thread(() -> {
        Database.init(this); // 耗时的放后台
    }).start();
    
  3. 启动任务分级(Android Startup库)
    implementation 'androidx.startup:startup-runtime:1.1.1'
    

大招2:闪屏页优化

错误做法

<!-- splash_activity.xml -->
<RelativeLayout>
    <ImageView android:src="@drawable/splash_bg"/>
    <ProgressBar android:layout_centerInParent="true"/>
</RelativeLayout>

正确方案

<!-- styles.xml -->
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_layer</item>
</style>

<!-- splash_layer.xml -->
<layer-list>
    <item android:drawable="@color/white"/>
    <item android:drawable="@mipmap/logo" android:gravity="center"/>
</layer-list>

关键点
👉 用windowBackground替代单独Activity
👉 真正的首页延后加载

大招3:主线程禁忌清单

🚫 不要在主线程做:

  • 读写SharedPreferences(用apply()替代commit()
  • 初始化网络库(Retrofit/OkHttp)
  • 加载大文件或数据库
  • 解析复杂JSON/XML

大招4:Class加载优化

android {
    defaultConfig {
        multiDexEnabled true
        // 指定主Dex需要的类
        multiDexKeepProguard file('multidex-config.pro')
    }
}

multidex-config.pro内容:

-keep class com.example.MainActivity
-keep class com.example.core.*

大招5:提前SharedPreferences

// App启动时预读(触发文件加载)
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
prefs.getAll(); // 关键!触发IO但不需要结果

大招6:延迟初始化

// 首页onCreate里延迟非关键任务
getWindow().getDecorView().post(() -> {
    // 延迟加载推荐内容
    loadRecommendData();
});

三、热启动优化三板斧

板斧1:保活Activity

// AndroidManifest.xml
<activity android:name=".MainActivity"
    android:launchMode="singleTask"
    android:alwaysRetainTaskState="true"/>

板斧2:缓存常用数据

// 用静态变量缓存(注意内存泄漏!)
public class CacheHolder {
    private static List<Data> hotData;
    
    public static void setHotData(List<Data> data) {
        hotData = data;
    }
    
    public static List<Data> getHotData() {
        return hotData;
    }
}

板斧3:避免重建View

@Override
protected void onSaveInstanceState(Bundle outState) {
    // 不保存复杂数据
    // super.onSaveInstanceState(outState); // 注释掉!
}

四、优化效果测量

1. 命令行测量

# 冷启动时间
adb shell am start-activity -W -n com.example/.MainActivity | grep TotalTime

# 输出示例:
TotalTime: 1234  # 单位毫秒

2. Android Studio Profiler

graph TD
    A[启动Profiler] --> B[选择CPU记录]
    B --> C[筛选"activityStart"]
    C --> D[查看关键阶段耗时]

3. 线上监控

// 代码埋点
long startTime = System.currentTimeMillis();
// ...启动完成后...
long costTime = System.currentTimeMillis() - startTime;
Firebase.analytics.logEvent("cold_start", bundleOf("time" to costTime));

五、避坑指南

1. 注意这些坑

  • MultiDex:4.4以下设备首次安装极慢
  • ContentProvider:会在Application.onCreate前初始化
  • 启动屏广告:增加2-3秒等待时间

2. 厂商差异

  • 小米/华为:会限制后台进程保活
  • OPPO/VIVO:默认关闭自启动
  • 解决方案:引导用户手动设置白名单

六、优化前后对比

指标优化前优化后提升
冷启动2500ms800ms68%
热启动800ms300ms62%
安装包大小50MB32MB36%

七、终极优化口诀

"Application要瘦,主线程要空,
闪屏用主题,任务分轻重,
热启保缓存,监控不能松"

把这些做到位,你的App启动速度就能飞起来! 🚀