-
Android) 안드로이드 12 Splash Screen 대응하기Android 2022. 3. 9. 18:12
Android 12의 변경 사항 중 하나인 Splash Screen Api를 적용하는 방법을 알아보려 합니다.
안드로이드 12 이전의 스플래시 화면 구현 방법은
- styles에 windowBackground 속성을 넣고, 스플래시를 보여줄 화면에 테마로 지정하는 방법
- 액티비티나 프래그먼트에 딜레이를 주어 직접 스플래시 화면을 보여주는 방법
위 방법들로 충분히 스플래시 화면을 구현할 수 있지만, 좀 더 유연함을 주기 위해 안드로이드 12에서 Splash Screen API가 추가되었습니다.
대표적으로 앱이 hot start에 있을 때도 위의 방법들은 다시 스플래시 화면을 보여줌으로써 대기시간이 길어져 사용자에게 불편함을 초래할 수 있습니다.
앱 시작 시간
- cold start : 앱이 처음부터 시작. cold start 전에는 앱의 프로세스를 만들지 않음. (기기 부팅, 앱이 처음 시작하는 경우)
- warm start : 메모리를 제거한 다음 앱을 다시 시작한 경우. (앱을 장시간 사용하지 않아 프로세스가 후순위로 밀려난 후에 앱을 실행한 경우)
- hot start : 백그라운드에 있는 앱을 포그라운드로 가져옴. 아직 메모리에 있는 상태. (짧은 시간 내에 다시 앱에 돌아오는 경우)
Android 12에서는 Splash Screen이 강제되어 따로 조치를 취하지 않으면 앱 아이콘이 스플래시 화면으로 적용이 되었습니다.
안드로이드 12에서 따로 액티비티나 프래그먼트에서 스플래시 화면을 구현해 놓았다면, 기본적으로 보여주는 스플래시와 구현한 스플래시가 차례대로 보이게 되어 스플래시 화면이 2번 보이게 됩니다.
Splash Screen API
Build.gradle
build.gradle android { compileSdkVersion 31 ... } dependencies { ... implementation 'androidx.core:core-splashscreen:1.0.0-beta01' }
- Splash Screen API를 대응하기 위해 아래와 같이 적용해줍니다.
themes.xml
themes.xml <?xml version="1.0" encoding="utf-8"?> <resources> <style name="Theme.App.Starting" parent="Theme.SplashScreen"> <item name="android:windowSplashScreenBackground">@color/...</item> <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item> <item name="android:windowSplashScreenAnimationDuration">1000</item> <item name=”android:windowSplashScreenIconBackground”>@color/...</item> <item name=”android:windowSplashScreenBrandingImage”>@drawable/...</item> <item name="postSplashScreenTheme">@style/Theme</item> <!-- 필요시 다크모드 같은 상황 고려. Status bar and Nav bar configs --> <item name="android:statusBarColor" tools:targetApi="l">@color/white</item> <item name="android:navigationBarColor">@color/white</item> <item name="android:windowLightStatusBar">true</item> </style> </resources>
- windowSpalshScreenBackground : 배경의 색을 지정
- windowSplashScreenAnimatedIcon : 화면 중앙에 아이콘 지정
- windowSplashScreenAnimationDuration : 스플래시 화면의 지속 시간 지정
- windowSplashScreenIconBackground : 스플래시 화면 아이콘 뒤의 배경 색 지정
- windowSplashScreenBrandImage : 스플래시 화면 하단에 표시할 이미지 지정 (권장 안함)
- postSplashScreenTheme : 스플래시 화면 후에 보일 화면의 테마 지정
Splash Screen 치수
- Branded image : 200 * 800dp
- App icon with an icon background : 240 * 240 dp
- App icon without an icon background : 288 * 288dp
- 공식문서에는 위와 같이 나와있지만, 실제로 아이콘에 위와 같은 dp를 적용해보면 생각했던 사이즈보다 훨씬 더 크게 아이콘이 스플래시 화면에 보입니다.
- 그래서 여백을 많이 주던가, 앱 아이콘 사이즈를 굉장히 많이 줄여야 비슷한 사이즈가 나왔습니다. 이 부분은 정확한 치수를 알기 힘들어서 곤란하네요..
- 참고 : https://stackoverflow.com/questions/69159905/is-possible-to-set-width-for-icon-in-android-12-splash-screens-api
manifest.xml
manifest.xml <application android:name=".MyApplication" .. android:theme="@style/Theme.App.Starting"> <activity android:name=".ui.MainActivity" android:exported="false" /> <activity android:name=".SplashActivity" android:theme="@style/Theme.App.Starting" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
- application 혹은 activity의 theme에 스플래시 테마 지정
스플래시를 보여줄 화면 지정
- onCreate의 super.onCreate() 이전에 installSplashScreen() 메서드를 추가해줍니다.
- installSplashScreen은 선택적으로 애니메이션을 지정하거나 더 길게 화면에 유지할 수 있는 객체를 반환합니다.
- SplashScreen#setKeepOnScreenCondition을 사용하여 스플래시 화면이 다음 화면으로 이동할 때 부드러운 전환이 가능합니다.
Activity class StartActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() super.onCreate(savedInstanceState) setContentView(R.layout.activity_start) } } @JvmStatic public fun Activity.installSplashScreen(): SplashScreen { val splashScreen = SplashScreen(this) splashScreen.install() return splashScreen } class StartActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { val splashScreen = installSplashScreen() super.onCreate(savedInstanceState) // Keep the splash screen visible for this Activity splashScreen.setKeepOnScreenCondition { true } startSomeNextActivity() finish() } ...
스플래시 화면을 더 오랫동안 유지
- 스플래시 화면은 첫 프레임을 그리는 즉시 닫힙니다.
- ViewTreeObserver.OnPreDrawListener을 활용해 첫 프레임을 그릴 때 사용할 수 있습니다.
// Create a new event for the activity. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Set the layout for the content view. setContentView(R.layout.main_activity) // Set up an OnPreDrawListener to the root view. val content: View = findViewById(android.R.id.content) content.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { // Check if the initial data is ready. return if (viewModel.isReady) { // The content is ready; start drawing. content.viewTreeObserver.removeOnPreDrawListener(this) true } else { // The content is not ready; suspend. false } } } ) }
스플래시 화면 닫기 애니메이션 설정
- Activity.getSplashScreen을 사용해 스플래시 화면의 애니메이션을 지정할 수 있습니다.
- 해당 콜백이 시작되면 스플래시 화면의 애니메이션 벡터 드로어블이 시작됩니다.
- 애니메이션의 시작 시점을 알기 위해서는 SplashScreenView.getIconAnimationStartMillis를 사용하여 알 수 있습니다.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // Add a callback that's called when the splash screen is animating to // the app content. splashScreen.setOnExitAnimationListener { splashScreenView -> // Create your custom animation. val slideUp = ObjectAnimator.ofFloat( splashScreenView, View.TRANSLATION_Y, 0f, -splashScreenView.height.toFloat() ) slideUp.interpolator = AnticipateInterpolator() slideUp.duration = 200L // Call SplashScreenView.remove at the end of your custom animation. slideUp.doOnEnd { splashScreenView.remove() } // Run your animation. slideUp.start() } } // Get the duration of the animated vector drawable. val animationDuration = splashScreenView.iconAnimationDurationMillis // Get the start time of the animation. val animationStart = splashScreenView.iconAnimationDurationMillis // Calculate the remaining duration of the animation. val remainingDuration = ( animationDuration - (SystemClock.uptimeMillis() - animationStart) ).coerceAtLeast(0L)
※ 실기기에서 구현해보는 것을 추천.
에뮬레이터로 확인할 시 첫 run에서 스플래시 아이콘이 화면에 보이지 않음.
에뮬레이터에서 직접 앱을 클릭하여 들어갈 때는 스플래시 아이콘이 화면에 보임.
Preference
A Comprehensive Guide to Android 12’s Splash Screen API
반응형'Android' 카테고리의 다른 글
Android) Kotlin Coroutines 1.6에서 도입된 테스트 API 사용해보기 (1) 2022.08.21 Android) Compose의 ConstraintLayout (0) 2022.06.01 Android) BroadcastReciever와 LiveData로 실시간 네트워크 연결 감지하기 (0) 2022.01.17 Android) Jetpack Compose에서 Paging 라이브러리 사용해보기 (0) 2021.12.04 Android) Jetpack Paging3 유닛 테스트 해보자 (0) 2021.11.28