Android - Başlangıçta beyaz ekranı önle


110

Hepimizin bildiği gibi, birçok Android uygulaması, ilk Activityodaklanmadan önce çok kısa bir süre beyaz bir ekran görüntüler . Bu sorun aşağıdaki durumlarda görülür:

  • Global Applicationsınıfı genişleten ve burada büyük başlatmalar gerçekleştiren Android uygulamaları . Application Nesne daima ilk önce oluşturulan Activitybu mantıklı, (ayıklayıcısında görülebilir bir gerçektir). Benim durumumdaki gecikmenin nedeni budur.

  • Açılış ekranından önce varsayılan önizleme penceresini görüntüleyen Android uygulamaları.

Belli android:windowDisablePreview = "true"ki ayar burada işe yaramıyor. Açılış ekranımın ana temasını buradaTheme.Holo.NoActionBar açıklandığı gibi ayarlayamıyorum , çünkü [maalesef] açılış ekranım bir .ActionBar

Bu arada, uzatmaz uygulamalar Applicationsınıfını yok açılışta beyaz ekranı gösterir.

Mesele şu ki, ideal olarak, Applicationnesnede gerçekleştirilen ilklendirmelerin , ilk gösterilmeden önce gerçekleşmesi gerekir Activity. Sorum şu Yani, nasıl uygulama başlangıçta bu başlatmalarını gerçekleştirebilirsiniz olmadan bir kullanarak Applicationnesneyi? Muhtemelen Threadveya kullanıyor Service, sanırım?

Bu, üzerinde düşünülmesi ilginç bir sorundur. NoActionBarTrajik bir şekilde, açılış ekranımın aslında ActionBarbazı ilgisiz nedenlerden dolayı bir nedeni olduğu için, olağan yolu ( temayı ayarlayarak ) atlayamıyorum .

Not:

Şu sorulara zaten değindim:

Referanslar:


1
Sorunu kendiniz buldunuz, uygulama bağlamında birçok init için yapıyorsunuz, aktivitenin yüklenmesini engelliyorsunuz, bunu senkronize etmeye çalışıyorsunuz, bir iş parçacığı sona erene kadar bir yükleme aktivitesi gösteriliyor.
AxelH

Bu yardımcı olabilir
Max

1
İdeal olarak, bir uygulama, işleme yükünü kaldırır ve ana iş parçacığını uzun işlemler için kullanmaz. Bu çok kabul gören bir uygulamadır. İşlemlerin uygulama yüklenmeden önce gerçekleşmesi gerekiyorsa, en azından UI ile bir iş parçacığı paylaşmamalıdır.
Beşoy Hanna

1
Tüm başlatma kodunu Applicationsınıfın dışına taşıdıktan sonra bunun hala bir sorun olduğunu fark edebilirsiniz . Bunun nedeni, Android'in uygulamaları "soğuk başlatma" yönteminin daha yeni sürümleridir. Google aslında bu yıl Google I / O'daki lansman zamanlarını ele aldı ve hatırladığım kadarıyla bu sorun N olarak düzeltilecek. Bu arada, Google'ın "markalı başlatma ekranı" dediği şeye bakmalısınız. İşte nasıl oluşturulacağına dair bir örnek: antonioleiva.com/branded-launch-screen - başlangıçta artık beyaz ekran yok ;-) Ve lütfen açılış ekranı kullanmayın - bu kullanıcı için can sıkıcı.
Darwind

1
Yanlış tema, işin püf noktası bir NoActionBar teması ayarlamak değil, ilk etkinliğin temasını ayarlamaktır, böylece boş bir temalı ekran tamamen başlatılmış gibi görünür.
zapl

Yanıtlar:


86

Beyaz arka planla ilgili sorun, uygulama belleğe yüklenirken android'in soğuk başlatılmasından kaynaklanır ve bununla önlenebilir:

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();
    }
}
}

Yerleşim

<?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 yüz

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

Bu temayı manifestteki açılış ekranınıza ekleyin

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

böyle bir etki yaratacak

meşgul bir kedi

daha fazla ayrıntı ve daha fazla çözüm için bu BlogPost'a bakabilirsiniz


3
hala beyaz ekran ve animasyon yardımcı
olmadı

Bu, basit bir uygulamadır. Soruna neden olan kodunuzun başka bölümleri olabilir. Lütfen başka bir soru açın ve size yardımcı olmak için orada
olalım

1
Bu sorunu, temalar arasında animasyon uygulayarak ve temayı çekilebilir değil, sadece arka renk aynı olacak şekilde değiştirerek ve ardından onWindowFocusChanged () ile içeriği görünür hale getirerek ve diğer akıllıca hareketlendirerek geçiş arasında da beyazlatarak çözdüm. temalar animasyon sürü yardımcı
Mehvish Ali

94

lütfen bu satırı uygulama temanıza ekleyin

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

daha fazla bilgi için: https://developer.android.com/topic/performance/vitals/launch-time#themed


25
Uygulamayı 2 saniye asın ve sonra uygulamayı başlatın, benim için kullanışlı değil!
Faakhir

4
grate şimdi #ffffff rengini göstermiyor ama şimdi gösteriyor # 000000
Midhilaj

@Faakhir Peki herhangi bir çözüm buldunuz mu? Hala bu beyaz ekranı kaldıran bir çözüm arıyorum ve ayrıca başlatma zamanında herhangi bir gecikme yok.
Rupam Das

33

Lütfen manifest uygulama temanızdaki bu iki satırı kopyalayıp yapıştırın, ör. Res / styles / AppTheme. o zaman cazibe gibi çalışacak ..

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


20

Bu sorunu çözmenin önerilen yolu cevaplarda eksiktir. Bu yüzden cevabımı buraya ekliyorum. Başlangıçta beyaz ekran sorunu, uygulamayı başlatırken sistem işleminin çizdiği ilk boş ekran nedeniyle oluşur. Bunu çözmenin yaygın bir yolu, bunu styles.xmldosyanıza ekleyerek bu başlangıç ​​ekranını kapatmaktır .

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

Ancak android belgelerine göre bu, daha uzun başlatma süresine neden olabilir. Google'a göre bu ilk beyaz ekrandan kaçınmanın önerilen yolu, etkinliğin windowBackgroundtema özniteliğini kullanmak ve başlangıç ​​etkinliği için basit bir özel çizim sağlamaktır.

Bunun gibi:

Drawable Layout dosyası, 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>

Yeni bir stil yaratın 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>

Bu temayı Manifest dosyasındaki başlangıç ​​etkinliğinize ekleyin

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

Ve aramadan setTheme(R.style.Apptheme)önce normal tema aramanıza geri dönmek istediğinizde super.onCreate()vesetContentView()

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);
    // ...
  }
}

Bu, sorunu çözmenin önerilen yoludur ve bu, google Materyal Tasarım modellerinden alınmıştır.


14

android:windowBackgroundBaşlatıcı etkinliğinizin temasındaki özniteliği bir renge veya çizilebilir olarak ayarlamayı denediniz mi?

Örneğin bu:

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

Başlatıcı etkinlik temasına eklendiğinde, başlangıçta siyah bir renk (beyaz renk yerine) gösterilir. Bu, kullanıcılarınıza bir şey gösterirken uzun başlatmayı gizlemek için kolay bir yöntemdir ve Uygulama nesnesini alt sınıflasanız bile iyi çalışır .

Uzun başlatma görevlerini yapmak için diğer yapıları (hatta Threads) kullanmaktan kaçının, çünkü bu tür yapıların yaşam döngüsünü kontrol edemeyebilirsiniz. Uygulama nesnesi, tam olarak bu tür eylemleri yapmak için doğru yerdir.


14

Temamda aşağıdaki iki satırı styles.xml altına ekledim

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

Büyü gibi çalıştı


10

Aynı sorunu yaşadım, tarzınızı güncellemelisiniz.

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>

Bildirim dosyanız aşağıdaki gibi görünmelidir.

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

Dışarı dışarı:

görüntü açıklamasını buraya girin

Umarım bu sana yardımcı olur.


2
Bu, bir NativeActivity OpenGL uygulamasında benim için harika çalışıyor. En eksiksiz ve en uygun cevap olduğu için bunun neden cevaplarda daha yukarıda olmadığından emin değilim. Hiçbir Java sadece birkaç XML dosyası değişikliği içermiyordu.
Slion

7

Yaşam döngüsü geri arama yöntemlerinde, kullanıcı etkinlikten ayrıldığında ve yeniden girdiğinde etkinliğinizin nasıl davranacağını bildirebilirsiniz. Android'in tasarlandığı şekilde, her bir uygulama için bir yaşam döngüsü olduğunu unutmayın. onCreate()Yönteme çok fazla yük koyarsanız (bu, düzen dosyalarını yüklemek ve içinde sahip olduğunuz tüm denetimleri başlatmak için kullanılan yöntemdir), düzen dosyasının yüklenmesi daha uzun süreceğinden beyaz ekran daha görünür hale gelecektir.

Bir aktiviteye başlarken birkaç farklı yöntem kullanmanızı öneririm. Bunlar onStart()(uygulama yüklendikten sonra ilk olarak adlandırılır) onActivityCreated()(düzen görüntülendikten sonra çağrılır ve etkinliği başlattıktan sonra herhangi bir veri işleme yapıyorsanız yararlıdır).

İşinizi kolaylaştırmak için, aşağıda resmi etkinlik yaşam döngüsü şeması verilmiştir:

görüntü açıklamasını buraya girin


Cevabınız için teşekkür ederim, çok ilginçti. Ancak, sorumu yanlış anladığınıza inanıyorum. Sorun ilkindeki başlatmalardan Activitydeğil, genel Applicationnesnede bulunanlardan kaynaklanıyor . Ve orada böyle bir kaygı ayrımı uygulayabileceğime inanmıyorum, çünkü Activitybunun aksine sadece bir onCreate()yöntemi var.
YS

Neden aktivite sınıfını değil de uygulama sınıfını genişletiyorsunuz?
Michele La Ferla

Tamam, yani Applicationnesneyi tamamen terk etmem ve tüm başlatma kodunu Activity
YS

Uygulamalarımı her zaman böyle geliştirdim, ancak tüm bu değişiklikleri yapmak istemiyorsanız, diğer yanıtlar uygulama sınıfını kullanarak sorununuzu çözmenize yardımcı olabilir. Gelecekteki referansınız için, hemen bir aktivite sınıfını ve ardından birçok parçayı kullanmanızı öneririm. Umarım bu yardımcı olur :)
Michele La Ferla

2

Başlatma yapmaya çalıştınız mı onActivityCreated?

İç Applicationsınıf:

 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

Arka plan işlemleri veya uygulama başlatma veya büyük dosyalar nedeniyle bu beyaz ekranın neden orada olduğunun zaten farkında olduğunuzdan, bunun üstesinden gelmek için aşağıdaki fikri kontrol edin.

Bu beyaz ekranı uygulamanın başlangıcında önlemek için, bir yol açılış ekranıdır, bu sadece nihai olmayan bir yoldur ve kullanmanız gerekir.

Splash.xml dosyanızdan açılış ekranı gösterdiğinizde, bu sorun da aynı kalacaktır,

Bu nedenle, açılış ekranı için style.xml dosyasında ont stili oluşturmanız ve orada pencere arka planını açılış resminiz olarak ayarlamanız ve ardından bu temayı manifest dosyasından açılış etkinliğinize uygulamanız gerekir. Yani şimdi uygulamayı çalıştırdığınızda, önce temayı ayarlayacak ve bu şekilde kullanıcı beyaz ekran yerine doğrudan sıçrama görüntüsünü görebilecek.


2

Her iki özellik de çalışır

    <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

Lütfen bunu bir kez deneyin.

1) Bir çekilebilir dosya oluşturun 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) Bunu styles.xml dosyasına koyun

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

3) AndroidMainfest.xml dosyanızda yukarıdaki temayı Başlatma etkinliği olarak ayarlayın.

       <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

Öğeyi values ​​/ styles.xml dosyasına yazmanız yeterlidir:

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

Örneğin, AppTheme'de:

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

Hata ayıklama sırasında bu beyaz ekrana sahip olan herkes, hata ayıklama yapıyorsanız, yüklemenin daha uzun süreceğini unutmayın. Sürüm APK'nızı oluşturur ve telefonunuza yüklerseniz, yüklemenin çok daha az sürdüğünü fark edeceksiniz.

Bu nedenle, hata ayıklama sürümüyle başlatma süresi, yayın sürümünün başlangıç ​​süresine eşit değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.