본문 바로가기

Android/공부

스플래시(Splash) 화면

안녕하세요? 닉네임간편입니다. 이번 시간에는 스플래시(Splash) 화면에 대해 알아보겠습니다.

1. 정의

스플래시(Splash) 화면은 앱이 실행되기 전에 잠깐 보였다가 사라지는 화면을 말합니다.

이 화면은 앱의 정보를 함축해서 보여줄 수도 있고, 메인 화면이 초기화될 때까지의 지루한 시간을 없애주는 역할도 합니다.

2. 만드는 법

스플래시 화면은 화면 단위이기 때문에 액티비티로 만듭니다. 그리고 메니페스트 파일에서 다음과 같이 인텐트 필터에 요소를 설정합니다.

<activity android:name=".SplashActivity"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="adjustPan">

이렇게 하면 스플래시 화면인 SplashActivity가 맨 처음으로 띄워질 수 있습니다.

스플래시 화면은 XML 레이아웃을 만들어 인플레이션하는 방식을 사용할 수도 있지만, 매니페스트 파일에서 theme 속성으로 스타일을 지정하는 방식을 사용합니다.

스플래시 화면은 앱을 시작할 때 로딩에 필요한 시간 동안 사용자가 지루해하지 않도록 띄워주는 화면입니다. 따라서 이 화면을 XML 파일로 설정하고 인플레이션 한다면 오히려 스플래시 화면을 로딩하는 데에도 시간이 걸리게 되고, 본래 목적을 달성하지 못하게 됩니다. 따라서 theme 속성으로 설정하는 것입니다.

[SplashTheme]

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_shape</item>
    <item name="android:fitsSystemWindows">true</item>
</style>

테마는 style 파일 안에 작성했습니다.

그리고 windowBackground에 이미지를 설정해서 다음과 같은 화면을 스플래시 화면을 띄웁니다.

[splash_shape]

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:drawable="@color/black"/>
    <item android:gravity="center">
        <bitmap
            android:src="@drawable/heart_selected"
            android:gravity="top"/>
    </item>
</layer-list>

layer-list를 사용해서 뒤에 배경을 설정함과 동시에 이미지를 하나 보여줍니다.

물론 이때 아예 이미지 하나를 전체로 보여줘도 됩니다.

그런데 이때 주의해야 할 사항이 있습니다.

기기별 해상도가 달라지면 스플래시 화면의 크기도 달라집니다.

그런데 스플래시 화면을 XML 파일로 만들지 않고 단지 비트맵에서 이미지를 사용할 경우, 이미지 크기를 조절할 수 있는 방법을 아직 찾지 못했습니다.

따라서 스플래시 화면에 이미지 전체를 사용하고 싶다면, 각 기기별 해상도에 맞는 크기의 이미지를 전부 사용해야 할 것 같습니다.

3. 사용하는 법

스플래시 액티비티에서 일정 시간 후 메인 액티비티로 전환되도록 코드를 작성합니다.

[SplashActivity]

class SplashActivity : AppCompatActivity() {
    var handler: Handler = Handler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handler.postDelayed(Runnable{
var intent: Intent = Intent(applicationContext, MainActivity::class.java)
            startActivity(intent)
            finish()
}, 1000)
    }
}

핸들러 객체를 사용해 1초 후에 메인 액티비티를 시작하도록 설정합니다.

그런데 API 레벨 30부터는 Handler의 생성자 중 2개가 deprecated 되었고, 위 생성자도 마찬가지입니다.

이 생성자가 deprecated된 이유는 다음과 같습니다.
Handler를 생성하는 동안 암묵적으로 Looper를 선택하는 것은 여러 가지 버그를 발생시킬 수 있습니다.
따라서 Executor를 사용하거나, 혹은 Looper를 명시적으로 선언해야 합니다.

1) 명시적으로 Looper 선언하는 방법

var handler: Handler = Handler(Looper.getMainLooper())

2) Executor 사용하는 방법

val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
        val mainExecutor: Executor = ContextCompat.getMainExecutor(this)

        backgroundExecutor.schedule({
            mainExecutor.execute {
                val intent = Intent(applicationContext, MainActivity2::class.java)
                startActivity(intent)
                finish()
            }
        }, 1, TimeUnit.SECONDS)

backgroundExecutor는 백그라운드에서 실행되는 Executor 객체이고, mainExecutor는 메인 스레드에서 실행되는 Executor 객체입니다.

schedule 메서드를 사용해 backgroundExecutor에 일정 시간이 지난 후 람다식 내의 코드를 실행하도록 설정할 수 있습니다.

이때 필요한 작업이 메인 액티비티 화면을 띄우는 것, 즉 UI 객체에 접근해야 하기 때문에 이 부분은 메인 스레드에서 실행되어야 합니다. 따라서 mainExecutor의 execute 메서드를 사용해 메인 액티비티를 시작하는 코드를 작성합니다. 그리고 finish() 메서드를 사용해 스플래시 화면을 종료합니다.

4. 마무리

이번 시간에는 스플래시 화면에 대해 알아보았습니다.

스플래시 화면은 대부분의 앱에서 사용하고 있기 때문에 알아두는 것이 좋습니다. 이번 기회에 잘 정리되었으면 좋겠습니다.

728x90
반응형