在安卓开发中,适配不同版本(特别是 Android 12+ 与旧版本)的 Splash 页面需要特别处理。以下是完整的兼容性解决方案:
一、整体适配策略
- Android 12+:使用新的
SplashScreen
API - Android 5.0-11:使用传统主题+Activity方案
- 保持一致的视觉效果:确保所有版本上的启动体验相似
二、具体实现步骤
1. 创建 Splash 主题
在 res/values/themes.xml
中:
<!-- 基础主题 -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- 应用通用样式 -->
</style>
<!-- 传统 Splash 主题(API 21-31) -->
<style name="AppTheme.Splash" parent="AppTheme">
<item name="android:windowBackground">@drawable/splash_background</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
2. 创建 Splash 背景 drawable
res/drawable/splash_background.xml
:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/splash_background_color"/>
<item android:gravity="center">
<bitmap
android:src="@mipmap/splash_logo"
android:gravity="center"/>
</item>
</layer-list>
3. 创建 SplashActivity
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// 在setContentView前设置主题(仅对旧版本有效)
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Android 12+ 处理
handleAndroid12Splash()
} else {
// 旧版本处理
handleLegacySplash()
}
}
@RequiresApi(Build.VERSION_CODES.S)
private fun handleAndroid12Splash() {
val splashScreen = installSplashScreen()
// 保持启动画面显示直到绘制完成
splashScreen.setKeepOnScreenCondition { true }
// 跳转主Activity
startMainActivity()
}
private fun handleLegacySplash() {
// 模拟加载过程(实际项目中替换为真实初始化代码)
Handler(Looper.getMainLooper()).postDelayed({
startMainActivity()
}, 1500) // 适当调整延时
}
private fun startMainActivity() {
startActivity(Intent(this, MainActivity::class.java))
finish()
// 添加过渡动画
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
}
}
4. 配置 AndroidManifest.xml
<application
android:name=".MyApplication"
android:theme="@style/AppTheme">
<!-- 启动Activity -->
<activity
android:name=".SplashActivity"
android:exported="true"
android:theme="@style/AppTheme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
5. Android 12+ 额外配置
在 res/values-v31/themes.xml
中:
<style name="AppTheme.Splash" parent="AppTheme">
<!-- 保持与旧版本相似的背景 -->
<item name="android:windowSplashScreenBackground">@color/splash_background_color</item>
<item name="android:windowSplashScreenAnimatedIcon">@mipmap/splash_logo</item>
<item name="android:windowSplashScreenAnimationDuration">200</item>
<!-- 其他Android 12特定属性 -->
</style>
三、版本兼容关键点
启动时间控制:
- 旧版本:使用
Handler.postDelayed
控制最小显示时间 - Android 12+:使用
setKeepOnScreenCondition
控制
- 旧版本:使用
视觉一致性:
- 确保所有版本的背景色和logo一致
- 调整图标大小和位置以获得相似效果
初始化优化:
// 在Application类中执行必要初始化 class MyApplication : Application() { override fun onCreate() { super.onCreate() // 执行全局初始化(网络库、数据库等) } }
测试要点:
- 冷启动、温启动场景
- 不同Android版本的表现
- 不同屏幕尺寸和方向的适配
四、高级优化技巧
动态主题适配:
if (isDarkMode()) { setTheme(R.style.AppTheme.Splash.Dark) } else { setTheme(R.style.AppTheme.Splash.Light) }
品牌动画(API 31+):
splashScreen.setOnExitAnimationListener { splashScreenView -> // 创建自定义退出动画 val fadeOut = ObjectAnimator.ofFloat( splashScreenView.iconView, View.ALPHA, 1f, 0f ) fadeOut.duration = 500L fadeOut.doOnEnd { splashScreenView.remove() } fadeOut.start() }
性能监控:
// 使用Jetpack Macrobenchmark库监控启动性能 class StartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = "com.example.myapp", metrics = listOf(StartupTimingMetric()), iterations = 5, startupMode = StartupMode.COLD ) { pressHome() startActivityAndWait() } }
五、常见问题解决方案
白屏/黑屏问题:
- 确保正确设置了
windowBackground
- 检查主题继承关系是否正确
- 确保正确设置了
启动图标变形:
- 提供多尺寸的启动图标
- 使用矢量图(VectorDrawable)
启动时间过长:
- 将非必要初始化延迟到主界面显示后
- 使用App Startup库优化组件初始化顺序
Android 12动画不生效:
- 确保targetSdkVersion设置为31或更高
- 检查主题中是否正确配置了SplashScreen相关属性
通过以上方案,可以实现在所有Android版本上一致的Splash体验,同时充分利用新版本API提供的优化功能。