web-dev-qa-db-ja.com

Android-起動時に白い画面を防ぐ

ご存知のように、多くのAndroidアプリは、最初のActivityがフォーカスされる前に非常に短時間白い画面を表示します。この問題は、次の場合に発生します。

  • グローバル Application クラスを拡張し、そこで主要な初期化を実行するAndroidアプリ。 Applicationオブジェクトは常に最初のActivity(デバッガーで観察できる事実)の前に作成されるため、これは理にかなっています。これが私の場合の遅延の原因です。

  • スプラッシュスクリーンの前にデフォルトのプレビューウィンドウを表示するAndroidアプリ。

Android:windowDisablePreview = "true"の設定は明らかにここでは機能しません。また、 here のように、スプラッシュスクリーンの親テーマをTheme.Holo.NoActionBarに設定することもできません。[残念ながら]スプラッシュスクリーンはActionBarを使用するためです。

一方、Applicationクラスを拡張しないアプリdo notは、起動時に白い画面を表示します。

問題は、理想的にはApplicationオブジェクトで実行される初期化は、最初のActivityが表示される前に発生する必要があることです。私の質問は、Applicationオブジェクトを使用して、アプリの起動時にこれらの初期化をどのように実行することができますかwithout?おそらくThreadまたはServiceを使用していると思いますか?

これは、考えるべき興味深い問題です。悲劇的なことに私のスプラッシュ画面には実際にはNoActionBarがあるため、通常の方法(ActionBarテーマを設定することで)をバイパスすることはできません。

注:

私はすでに次の質問に言及しています。

参照:

78
AndroidCarina

白い背景の問題は、アプリがメモリにロードされている間にAndroidがコールドスタートするために発生します。これはこれで回避できます。

public class OnboardingWithCenterAnimationActivity extends AppCompatActivity {
public static final int STARTUP_DELAY = 300;
public static final int ANIM_ITEM_DURATION = 1000;
public static final int ITEM_DELAY = 300;

private boolean animationStarted = false;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    setTheme(R.style.AppTheme);
    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_onboarding_center);
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {

    if (!hasFocus || animationStarted) {
        return;
    }

    animate();

    super.onWindowFocusChanged(hasFocus);
}

private void animate() {
    ImageView logoImageView = (ImageView) findViewById(R.id.img_logo);
    ViewGroup container = (ViewGroup) findViewById(R.id.container);

    ViewCompat.animate(logoImageView)
        .translationY(-250)
        .setStartDelay(STARTUP_DELAY)
        .setDuration(ANIM_ITEM_DURATION).setInterpolator(
            new DecelerateInterpolator(1.2f)).start();

    for (int i = 0; i < container.getChildCount(); i++) {
        View v = container.getChildAt(i);
        ViewPropertyAnimatorCompat viewAnimator;

        if (!(v instanceof Button)) {
            viewAnimator = ViewCompat.animate(v)
                    .translationY(50).alpha(1)
                    .setStartDelay((ITEM_DELAY * i) + 500)
                    .setDuration(1000);
        } else {
            viewAnimator = ViewCompat.animate(v)
                    .scaleY(1).scaleX(1)
                    .setStartDelay((ITEM_DELAY * i) + 500)
                    .setDuration(500);
        }

        viewAnimator.setInterpolator(new DecelerateInterpolator()).start();
    }
}
}

レイアウト

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="?colorPrimary"
Android:orientation="vertical"
>

<LinearLayout
    Android:id="@+id/container"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:gravity="center"
    Android:orientation="vertical"
    Android:paddingTop="144dp"
    tools:ignore="HardcodedText"
    >

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center_horizontal"
        Android:layout_marginTop="16dp"
        Android:alpha="0"
        Android:text="Hello world"         Android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
        Android:textColor="@Android:color/white"
        Android:textSize="22sp"
        tools:alpha="1"
        />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center_horizontal"
        Android:layout_marginTop="8dp"
        Android:alpha="0"
        Android:gravity="center"
        Android:text="This a Nice text"
      Android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle.Inverse"
        Android:textSize="20sp"
        tools:alpha="1"
        />

    <Button
        Android:id="@+id/btn_choice1"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="48dp"
        Android:scaleX="0"
        Android:scaleY="0"
        Android:text="A Nice choice"
        Android:theme="@style/Button"
        />

    <Button
        Android:id="@+id/btn_choice2"
        Android:layout_width="200dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="4dp"
        Android:scaleX="0"
        Android:scaleY="0"
        Android:text="Far better!"
        Android:theme="@style/Button"
        />

</LinearLayout>

<ImageView
    Android:id="@+id/img_logo"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:src="@drawable/img_face"
    tools:visibility="gone"
    />
</FrameLayout>

imgフェイス

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:opacity="opaque">

<item Android:drawable="?colorPrimary"/>
<item>
    <bitmap
        Android:gravity="center"
        Android:src="@drawable/img_face"/>
</item>

このテーマをマニフェストのスプラッシュスクリーンに追加します

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="Android:windowBackground">@null</item>
</style>

<style name="AppTheme.CenterAnimation">
    <item name="Android:windowBackground">@drawable/ll_face_logo</item>
</style>

このような効果が得られます

a busy cat

詳細とソリューションについては、これを確認できます BlogPost

66

この行をアプリのテーマに追加してください

<item name="Android:windowDisablePreview">true</item>
56
Hitesh Singh

まず、白い画面を削除するには、これを読んでください- https://www.bignerdranch.com/blog/splash-screens-the-right-way/

しかし、より重要なことは、初期ロードを最適化し、実行する時間があるときに重い作業を延期することです。ご覧になりたい場合は、ここにアプリケーションクラスを投稿してください。

17
Shmuel

マニフェストアプリのテーマ(res/styles/AppTheme)にこれらの2行をコピーして貼り付けてください。それは魅力のように動作します。

<item name="Android:windowDisablePreview">true</item>
<item name="Android:windowIsTranslucent">true</item>
16
prasad reddy

ランチャーアクティビティのテーマで、Android:windowBackground属性を色またはドロアブルに設定しようとしましたか?

たとえば、次のとおりです。

<item name="Android:windowBackground">@Android:color/black</item>

launcherアクティビティテーマに追加すると、起動時に(白い色ではなく)黒い色が表示されます。これは、ユーザーに何かを表示しながら、長い初期化を非表示にする簡単なトリックです。Applicationオブジェクトをサブクラス化しても、および正常に動作します

長い初期化タスクを実行するために他の構造(スレッドも含む)を使用しないでください。そのような構造のライフサイクルを制御できなくなる可能性があるためです。 Applicationオブジェクトは、まさにこのタイプのアクションを実行するための正しい場所です。

8
George Metaxas

ライフサイクルコールバックメソッド内で、ユーザーがアクティビティを離れて再入力したときのアクティビティの動作を宣言できます。 Androidの設計方法には、すべてのアプリにライフサイクルがあることに注意してください。 onCreate()メソッド(レイアウトファイルをロードし、その中にあるコントロールを初期化するために使用されるメソッド)にあまりにも多くの負荷をかけると、レイアウトファイルのロードに時間がかかるため、白い画面が見やすくなります。

アクティビティを開始するとき、いくつかの異なる方法を使用することをお勧めします。 onStart()(アプリが読み込まれたときに最初に呼び出される)、onActivityCreated()(レイアウトが表示された後に呼び出され、アクティビティの開始時にデータ処理を行う場合に便利です)。

簡単にするために、公式のアクティビティライフサイクル図を以下に示します。

enter image description here

7

同じ問題がありました。スタイルを更新する必要があります。

style.xml

<!-- Base application theme. -->
 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <!-- Customize your theme here. -->
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
        <item name="Android:windowNoTitle">true</item>
        <item name="Android:windowDisablePreview">true</item>
        <item name="Android:windowBackground">@null</item>
        <item name="Android:windowIsTranslucent">true</item>

 </style>

マニフェストファイルは次のようになります。

<application
        Android:name=".MyApplication"
        Android:allowBackup="true"
        Android:icon="@mipmap/ic_launcher"
        Android:label="@string/app_name"
        Android:theme="@style/AppTheme">
     // Other stuff
</application>

Outout:

enter image description here

これがあなたのお役に立てば幸いです。

6
Hiren Patel

この問題を解決するための推奨される方法が回答にありません。そこで、ここに答えを追加します。起動時のホワイトスクリーンの問題は、アプリの起動時にシステムプロセスが描画する最初のブランク画面が原因で発生します。これを解決する一般的な方法は、styles.xmlファイルにこれを追加してこの初期画面をオフにすることです。

<item name="Android:windowDisablePreview">true</item>

ただし、Androidのドキュメントによると、これにより起動時間が長くなる可能性があります。 googleによると、この最初の白い画面を回避するための推奨される方法は、アクティビティのwindowBackgroundテーマ属性を使用して、開始アクティビティ用のシンプルなカスタム描画を提供することです。

このような:

描画可能レイアウトファイル、my_drawable.xml

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:opacity="opaque">
  <!-- The background color, preferably the same as your normal theme -->
  <item Android:drawable="@Android:color/white"/>
  <!-- Your product logo - 144dp color version of your app icon -->
  <item>
    <bitmap
      Android:src="@drawable/product_logo_144dp"
      Android:gravity="center"/>
  </item>
</layer-list>

styles.xmlに新しいスタイルを作成します

<!-- Base application theme. -->
<style name="AppTheme">
    <!-- Customize your theme here. -->               
</style>

<!-- Starting activity theme -->
<style name="AppTheme.Launcher">
    <item name="Android:windowBackground">@drawable/my_drawable</item>
</style>

このテーマをマニフェストファイルの開始アクティビティに追加します

<activity ...
Android:theme="@style/AppTheme.Launcher" />

そして、通常のテーマに戻る場合は、setTheme(R.style.Apptheme)super.onCreate()を呼び出す前にsetContentView()を呼び出します。

public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // Make sure this is before calling super.onCreate
    setTheme(R.style.Theme_MyApp);
    super.onCreate(savedInstanceState);
    // ...
  }
}

これは問題を解決するための推奨される方法であり、これはgoogle Material Design パターンからのものです。

4
Sam

テーマのstyles.xmlの下に次の2行を追加しました

    <item name="Android:windowDisablePreview">true</item>
    <item name="Android:windowBackground">@null</item>

魔法のように働いた

3

onActivityCreatedに初期化を設定しようとしましたか?

Applicationクラス内:

 registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if(activity.getClass().equals(FirstActivity.class) {
                    // try without runOnUiThread if it will not help
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            new InitializatioTask().execute();
                        }
                    });
                }
            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
2

バックグラウンドプロセスやアプリケーションの初期化、または大きなファイルが原因でこの白い画面が表示される理由は既にわかっているので、これを克服するためのアイデアを以下で確認してください。

アプリの開始時にこの白い画面を防ぐための1つの方法はスプラッシュスクリーンです。これは最終的な方法ではなく、使用する必要があります。

Splash.xmlファイルからスプラッシュ画面を表示する場合、この問題も同じままです。

したがって、スプラッシュスクリーン用にstyle.xmlファイルでontスタイルを作成し、ウィンドウの背景をスプラッシュイメージとして設定し、そのテーマをマニフェストファイルからスプラッシュアクティビティに適用する必要があります。アプリを実行すると、最初にテーマが設定され、この方法により、ユーザーは白い画面ではなく直接スプラッシュ画像を見ることができます。

2
Vickyexpert

両方のプロパティが機能します

    <style name="AppBaseThemeDark" parent="@style/Theme.AppCompat">
            <!--your other properties -->
            <!--<item name="Android:windowDisablePreview">true</item>-->
            <item name="Android:windowBackground">@null</item>
            <!--your other properties -->
    </style>
2
Sohail Zahid

Values/styles.xmlにアイテムを書くだけです:

<item name="Android:windowBackground">@Android:color/black</item>

たとえば、AppThemeの場合:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="Android:windowFullscreen">true</item>
    <item name="Android:windowContentOverlay">@null</item>

    <item name="Android:windowBackground">@Android:color/black</item>

    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>
0
Javier Reinoso
Style :- 
<style name="SplashViewTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="Android:windowBackground">@drawable/splash</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

In Manifest :- 
<activity Android:name=".SplashActivity"
        Android:theme="@style/SplashViewTheme">
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
0
Krishna

これを一度試してください。

1)描画可能なファイルsplash_background.xmlを作成します

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@color/{your color}" />

    <item>
        <bitmap
            Android:layout_width="@dimen/size_250"
            Android:layout_height="@dimen/size_100"
            Android:gravity="center"
            Android:scaleType="fitXY"
            Android:src="{your image}"
            Android:tint="@color/colorPrimary" />
    </item>

</layer-list>

2)これをstyles.xmlに入れます

     <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
         <item name="Android:windowBackground">@drawable/background_splash</item>
     </style>

3)AndroidMainfest.xmlで、上記のテーマを起動アクティビティに設定します。

       <activity
            Android:name=".SplashScreenActivity"
            Android:screenOrientation="portrait"
            Android:theme="@style/SplashTheme"
            Android:windowSoftInputMode="stateVisible|adjustResize">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />

                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
0
Surendar D