Android と Qt Splash Screen

このブログは「Android and Qt Splash Screen」の抄訳です。

Android 12 以降、Android はデフォルトのスプラッシュスクリーン用 API を提供しています。SplashScreen API を使用すると、アプリアイコンを表示し、アプリへ遷移するアニメーションと共にアプリを起動することが可能です。Android のデフォルト起動では、アプリアイコンが画面中央へズームインし、その後アプリの最初のビューへ遷移します。Qtでもスプラッシュスクリーンが定義されている場合、Androidのスプラッシュスクリーン表示後にQtのスプラッシュスクリーンが表示されるため、ユーザー体験に違和感を生じさせる可能性があります。

Android向けQtスプラッシュスクリーンのドキュメントは、マニフェスト、QML、関数に関する記述が少なく、あまり簡潔ではありません。

マルチプラットフォームアプリケーションにおいて、AndroidスプラッシュスクリーンからQtスプラッシュスクリーンへのスムーズな遷移を実現するには、Androidスプラッシュスクリーンの可視性を最小限に抑える方法があります。これにはAndroidマニフェストおよびリソースファイルへの変更が必要です。QtのスプラッシュスクリーンがAndroidの起動アニメーションと良好に連携する様子を示すため、2つのサンプルを追加しました。

サンプルはQt for Androidのページでご覧いただけます。

以下に、サンプルにおける重要な部分を記載します。詳細については、サンプルのドキュメントをご参照ください。

スプラッシュスクリーンアクティビティ 

<activity 
  Android:name=".SplashActivity" 
  Android:exported="true" 
  Android:label="QML Splash Screen Example" 
  Android:theme="@style/splashStartTheme"> 
  <intent-filter> 
    <action Android:name="Android.intent.action.MAIN" /> 
    <category Android:name="Android.intent.category.LAUNCHER" /> 
  </intent-filter> 
</activity> 

 

AndroidManifest.xmlでは、アプリは専用のスプラッシュスクリーンアクティビティで起動し、メインアプリケーションアクティビティはマニフェスト内に別のエントリとして含まれています。

スプラッシュ画面のテーマ設定

<style name="splashStartTheme"> 
  <item name="Android:windowNoTitle">true</item> 
  <item name="Android:windowDisablePreview">true</item> 
  <item name="Android:windowIsTranslucent">true</item> 
</style> 

 

テーマ XML ファイルにおいて、Android:windowDisablePreview を true に設定すると初期の空白画面が非表示となりますが、Android:windowIsTranslucent を true に設定することは必須です。これにより Android スプラッシュ画面の透過が可能となります。

ウィンドウの半透明化が、AndroidManifestに2つのアクティビティを必要とする理由です。ビューの初期化後に半透明性を変更することはできず、アプリケーションの向き変更機能を無効にします。ビューが半透明の場合、Androidは通常アプリドロワーである基底ビューから向きを取得し、向きを変更しません。

スプラッシュ画面のJavaクラス抜粋

// Set up an OnPreDrawListener to the root view. 
final View content = findViewById(android.R.id.content); 
content.getViewTreeObserver().addOnPreDrawListener( 
    new ViewTreeObserver.OnPreDrawListener() { 
        @Override 
        public boolean onPreDraw() { 
            Intent i = new Intent(SplashActivity.this, QtActivity.class); 
            i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 
            startActivity(i); 
 
            content.getViewTreeObserver().removeOnPreDrawListener(this); 
            finish(); 
            return true; 
        } 
    });

 

実際のアプリを起動するには、Androidが自身を設定するのを待つ必要があります。そのため、スプラッシュスクリーンアクティビティを定義し、onCreate関数をオーバーライドします。この関数内でonPreDrawListenerを追加します。このリスナーは、最初のビューが描画可能になった時点で呼び出されます。この時点で、Qtアクティビティを起動できます。このアクティビティには別のテーマを定義し、Android:windowDisablePreview および Android:windowIsTranslucent をfalseに設定し直しています。

以降は、アプリはQtアプリケーションとして動作し、Qtスプラッシュスクリーンを表示した後、最初のアプリケーションビューに移行します。Pixel 6aで動作する例を短い動画でご覧ください。

QMLでのスプラッシュスクリーン


XMLによるスプラッシュスクリーン 

クロスプラットフォームの一貫性

Qtスプラッシュスクリーンは、プラットフォームを問わず一貫したアプリケーション起動体験を提供します。マルチプラットフォームでの一貫性が不要な場合、Androidスプラッシュスクリーンは起動シーケンスにおいてより早期に実行されるというわずかな利点があります。これは性能の低いデバイスでより顕著になる可能性がありますが、Qtアプリを適切に設計すれば、その差はほとんど気にならない程度になります。Androidスプラッシュスクリーンの実装に関する詳細は、ドキュメントに記載されています。

ウィジェットやQSplashScreenの使用例は省略されていますが、Androidスプラッシュ画面を最小化する「同一アクティビティ–テーマ」の原則はここにも適用されます。QSplashScreenの近代化に向けた取り組みはJiraで追跡されています。

スプラッシュ画面のサンプルがQt 6.10に追加されました。これらのサンプルはJiraで管理されており、本機能に関するご意見やアイデアを歓迎いたします。Jiraエピックへのリンクはこちらです


Blog Topics:

Comments