Programing

Android-시작시 흰색 화면 방지

crosscheck 2020. 9. 5. 08:48
반응형

Android-시작시 흰색 화면 방지


우리 모두 알다시피, 많은 Android 앱은 첫 번째 Activity초점을 맞추기 전에 매우 짧은 시간 동안 흰색 화면을 표시합니다 . 이 문제는 다음과 같은 경우에 나타납니다.

  • 전역 Application클래스 를 확장하고 그 안에서 주요 초기화를 수행 하는 Android 앱 . Application객체는 항상 첫 번째 전에 만든 Activity이 의미가 있도록 (디버거에서 관찰 할 수있는 사실). 이것이 제 경우 지연의 원인입니다.

  • 스플래시 화면 앞에 기본 미리보기 창을 표시하는 Android 앱.

설정은 android:windowDisablePreview = "true"분명히 여기서 작동하지 않습니다. [불행히도] 내 스플래시 화면이 .NET Framework를 사용하기 때문에 스플래시 화면의 상위 테마를 여기Theme.Holo.NoActionBar설명 된대로 설정할 수 없습니다 .ActionBar

한편, Application클래스를 확장하지 않는 앱 은 시작할 때 흰색 화면이 표시 되지 않습니다 .

문제는 이상적으로는 Application객체 에서 수행되는 초기화 가 첫 번째 항목 이 표시 되기 전에 발생해야한다는 것 Activity입니다. 그래서 제 질문은 객체 사용 하지 않고 앱 시작시 이러한 초기화를 어떻게 수행 할 수 Application있습니까? Thread또는을 사용하는 것 같습니다 Service.

이것은 생각할 흥미로운 문제입니다. NoActionBar비극적으로 내 스플래시 화면에는 실제로 ActionBar관련없는 이유 있기 때문에 일반적인 방식으로 ( 테마 를 설정하여 ) 우회 할 수 없습니다 .

노트 :

나는 이미 다음 질문을 언급했습니다.

참조 :


흰색 배경의 문제는 앱이 메모리에로드되는 동안 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>

다음과 같은 효과를 생성합니다.

바쁜 고양이

자세한 내용과 더 많은 솔루션을 보려면이 BlogPost를 확인하십시오.


이 줄을 앱 테마에 추가하세요

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

이 두 줄을 매니페스트 앱 테마 (예 : res / styles / AppTheme)에 복사하여 붙여 넣으십시오. 그러면 매력처럼 작동합니다 ..

<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>

먼저 흰색 화면을 제거하려면 https://www.bignerdranch.com/blog/splash-screens-the-right-way/를 읽으십시오.

그러나 더 중요한 것은 초기로드를 최적화하고 실행 시간이있을 때 무거운 작업을 연기하는 것입니다. 우리가 살펴 보길 원한다면 여기에 애플리케이션 클래스를 게시하십시오.


android:windowBackground런처 활동 테마의 속성을 색상 또는 드로어 블로 설정해 보셨습니까 ?

예를 들면 다음과 같습니다.

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

런처 활동 테마에 추가하면 시작시 흰색이 아닌 검은 색으로 표시됩니다. 이것은 긴 초기화를 숨기고 사용자에게 무언가를 보여주는 쉬운 트릭 이며 Application 개체를 하위 클래스로 분류하더라도 제대로 작동 합니다.

긴 초기화 작업을 수행하는 데 다른 구성 (스레드 포함)을 사용하지 마십시오. 이러한 구성의 수명주기를 제어 할 수 없게 될 수 있습니다. Application 개체는 이러한 유형의 작업을 정확하게 수행하기위한 올바른 위치입니다.


이 문제를 해결하는 권장 방법이 답변에 없습니다. 그래서 여기에 내 대답을 추가하고 있습니다. 시작시 흰색 화면 문제는 앱을 시작할 때 시스템 프로세스가 그리는 초기 빈 화면 때문에 발생합니다. 이 문제를 해결하는 일반적인 방법은 styles.xml파일 에 추가하여이 초기 화면을 끄는 것 입니다.

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

그러나 안드로이드 문서에 따르면 이것은 더 긴 시작 시간을 초래할 수 있습니다. 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>

이 테마를 Manifest 파일의 시작 활동에 추가하십시오.

<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 패턴 에서 가져온 것 입니다.


수명주기 콜백 메서드 내에서 사용자가 활동을 떠났다가 다시 들어갈 때 활동이 어떻게 작동하는지 선언 할 수 있습니다. Android가 설계된 방식에는 각 앱마다 수명주기가 있습니다. onCreate()메서드 에 너무 많은로드를 가하면 (레이아웃 파일을로드하고 그 안에있는 컨트롤을 초기화하는 데 사용되는 방법) 레이아웃 파일을로드하는 데 시간이 더 오래 걸리므로 흰색 화면이 더 잘 보입니다.

활동을 시작할 때 여러 가지 방법을 사용하는 것이 좋습니다. 하는 이러한 onStart()(응용 프로그램이로드되면 제일 먼저로 호출되는), onActivityCreated()(당신이 활동을 시작하기에 모든 데이터 처리를 만드는 경우 레이아웃을 표시 한 후 호출하고 유용한되는).

더 쉽게하기 위해 다음은 공식 활동 라이프 사이클 다이어그램입니다.

여기에 이미지 설명 입력


같은 문제가 있었는데 스타일을 업데이트해야합니다.

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>

아웃 아웃 :

여기에 이미지 설명 입력

이것이 당신을 도울 수 있기를 바랍니다.


styles.xml 아래의 테마에 다음 두 줄을 추가했습니다.

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

매력처럼 일했다


초기화를 시도 했습니까 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) {

            }
        });

백그라운드 프로세스 또는 응용 프로그램 초기화 또는 대용량 파일로 인해이 흰색 화면이있는 이유를 이미 알고 있으므로 아래 아이디어를 확인하여 극복하십시오.

앱 시작시이 흰색 화면을 방지하려면 한 가지 방법은 스플래시 화면입니다. 이것은 최종 방법이 아니므로 사용해야합니다.

splash.xml 파일에서 스플래시 화면을 표시하면이 문제도 동일하게 유지됩니다.

따라서 스플래시 화면을 위해 style.xml 파일에 ont 스타일을 생성해야하고 거기에서 창 배경을 스플래시 이미지로 설정 한 다음 해당 테마를 매니페스트 파일에서 스플래시 활동에 적용해야합니다. 이제 앱을 실행할 때 먼저 테마를 설정하고 이렇게하면 사용자가 흰색 화면 대신 스플래시 이미지를 직접 볼 수 있습니다.


두 속성 모두 작동

    <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>

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>

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>

한번 시도해주세요.

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에서 위의 테마를 Launch 활동으로 설정하십시오.

       <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>

참고 URL : https://stackoverflow.com/questions/37437037/android-prevent-white-screen-at-startup

반응형