Android 12がリリースされ、話題にされる機能の一つとしてあげられるのはOS提供のSplashScreenではないでしょうか。長いAndroidの歴史の中で、様々な方法で実装してきたスプラッシュスクリーンがついにファーストパーティからの提供があって、ますますOSの統一感を感じられますね。

Android 12からは何もせずでも表示されるスプラッシュスクリーンですが、それ以前のバージョンでは対応されませんので、そのためにAndroidXのサポートライブラリからCore.SplashScreenがリリースされました。現在まだアルファ版ですが、対応バージョンはAPI 23(Android 6.0 Marshmallow)までとなります。

残念なことに、Android 12以降のスプラッシュスクリーンを無効化する方法がないため、既存アプリの場合は既存のスプラッシュスクリーン実装を調整する必要があります。複雑な起動シーケンスがなければサポートライブラリを入れるだけで対応可能ですが、読み込み処理等があってスプラッシュの表示時間を長くする必要がある場合は少し追加の対応が必要です。今回はサポートライブラリを用いて実際に様々なAPIレベルでスプラッシュスクリーンの実装を行ってみようと思います。

サポートライブラリを入れてみよう!

サポートライブラリを使うには、build.gradle に以下のパッケージを追加します。

implementation "androidx.core:core-splashscreen:1.0.0-alpha01"

また、SplashScreenのサポートライブラリを使用するにはアプリをAPI 31以降でコンパイルする必要があります。

android {
    compileSdkVersion 31
}

これらをgradleファイルに追加すれば準備完了です!早速使ってみましょう!

Core SplashScreen APIを実装してみましょう!

API 23までの対応であれば、メインとなるアクティビティ(一般的にはMainActivity)のonCreateで、setContentViewの前に、スプラッシュスクリーンをインストールする必要があります。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        installSplashScreen()   // ←これを先に呼び出す!
        setContentView(R.layout.activity_main)
    }
}

API 23以前のバージョンを対応する必要があれば、いくつかの方法はありますが、その中で最も使いやすい簡易スプラッシュスクリーン実装を用いて対応できます。

SplashScreen APIでも、スプラッシュ用のテーマが必要ですが、テーマの切り替えはAPI側が行うのでActivityからの明示的な切り替えは不要です。

次は、スプラッシュ用のテーマを追加します。

API 23未満
<style name="AppTheme.Splash" parent="AppTheme.NoActionBar">
    <item name="android:windowBackground">@drawable/legacy_splash_screen</item>
    <item name="colorPrimaryDark">@color/white</item>
</style>

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <!-- アプリ用のメインテーマはこちら -->
</style>

<style name="AppTheme.NoActionBar" parent="AppTheme">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

SplashScreen APIに対応されないAPIレベルは、簡易的なスプラッシュスクリーンで対応できます。スプラッシュスクリーン用のテーマを同じ名前で追加するとAPIレベル分けでどちらでも対応できます。ここで最も重要なところは、android:windowBackgroundのアトリビュートです。このバックグラウンドがスプラッシュスクリーンになりますので、表示するアイコンと背景は一つのdrawableでまとめておけばいいです。

例えば、以下のようなシンプルなXMLリソースでも十分です。アイコンのサイズはそのまま利用されるので、144dpぐらいがちょうどいいと言われることが多いです。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 背景色:メインテーマの背景色に合わせる -->
    <item android:drawable="@color/white" />

    <!-- アイコン:スプラッシュで表示されるアイコン -->
    <item android:drawable="@drawable/ic_launcher_round" />

</layer-list>
API 23以降
<style name="AppTheme.Splash" parent="Theme.SplashScreen">
    <item name="windowSplashScreenBackground">@color/white</item>
    <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
    <item name="postSplashScreenTheme">@style/AppTheme</item>
</style>

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <!-- アプリ用のメインテーマはこちら -->
</style>

SplashScreen APIを利用できると、スプラッシュスクリーン用のテーマをTheme.SplashScreenを継承するものであれば十分なので、その中に重要なアトリビュートは以下の通りです。

  • windowSplashScreenBackground – スプラッシュスクリーンの背景色、メインテーマに合わせる
  • windowSplashScreenAnimatedIcon – スプラッシュ用のアイコン、ランチャーのアイコンのmipmapやアニメーション付きのアイコンも使用可能なので自由度高め
  • postSplashScreenTheme – スプラッシュスクリーン後のテーマ、メインテーマをここに設定する

特にpostSplashScreenThemeはとても重要で、設定し忘れる場合は(Theme.SplashScreenTheme.AppCompatを継承しないため)以下のエラーでアプリが強制終了してしまう場合があります。

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

あとは、Manifestファイルにスプラッシュ用のテーマを設定すると、

<application
    ...     
    android:theme="@style/AppTheme.Splash">
    ...
</application>

スプラッシュスクリーンの実装が完了しました!

実際にSplashScreen APIを動かしてみました

以下はそれぞれAPI 21、API 29、API 31のスプラッシュ画面の表示です。統一感があって綺麗だと思いませんか?

API 21でのスプラッシュスクリーン
API 29でのスプラッシュスクリーン
API 31でのスプラッシュスクリーン

応用編:初期化処理等、起動時の処理の間にスプラッシュを表示し続けてみた

ここまではスプラッシュスクリーンを一通り実装してみましたが、実際のアプリではスプラッシュが表示される中、様々な初期化処理や起動時処理が行われるケースが多いです。ゲームなど、特別なローディング画面がある場合はスプラッシュで処理を行うことが少ないが、ほとんどの場合はスプラッシュ表示を処理中の間保ち続けたいと思います。

デフォルトの実装だと、アクティビティが最初のフレームを描画し始めたらスプラッシュが非表示されてしまいます。そうならないように、以下の対策が取られます。

  • API 23未満:setThemeの呼び出しを初期化処理等の終了時に行う。ただしsetContentViewもセットで待機させる必要がある。非同期処理の場合は実装が少々難しくなる。
  • API 23以降:installSplashScreen()の返り値でSplashScreenのオブジェクトをもらえるので、SplashScreen#setKeepVisibleCondition(SplashScreen.KeepOnScreenCondition)を設定すればいい。

SplashScreen.KeepOnScreenConditionは、Boolean値でスプラッシュを保つかどうかを判定します。スプラッシュを維持したい場合はtrueを返し、処理が全て完了しスプラッシュを非表示にしたい場合はfalseを返します。

終わりに

いかがでしょうか。この記事は主に新規アプリでSplashScreen APIを適用したい方々向けで作成されております。既存アプリの場合は公式ページでマイグレーションの手順がありますので参考にするといいと思います!これでスプラッシュの作成が少しは楽になりましたね!

参考



ギャップロを運営しているアップフロンティア株式会社では、一緒に働いてくれる仲間を随時、募集しています。 興味がある!一緒に働いてみたい!という方は下記よりご応募お待ちしております。
採用情報をみる