2016-05-25 13 views
49

Như chúng ta đã biết, nhiều ứng dụng Android hiển thị màn hình trắng rất ngắn trước khi tập trung Activity đầu tiên của chúng. Vấn đề này được quan sát thấy trong các trường hợp sau đây:Android - Ngăn màn hình trắng lúc khởi động

  • Android ứng dụng mở rộng các lớp Application toàn cầu và thực hiện khởi tạo lớn trong đó. Đối tượng Application luôn được tạo trước Activity đầu tiên (thực tế có thể được quan sát thấy trong trình gỡ lỗi), do đó điều này có ý nghĩa. Đây là nguyên nhân của sự chậm trễ trong trường hợp của tôi.

  • Ứng dụng Android hiển thị cửa sổ xem trước mặc định trước màn hình giật gân.

Thiết lập android:windowDisablePreview = "true" rõ ràng không hoạt động ở đây. Tôi cũng không thể đặt chủ đề gốc của màn hình giật gân thành Theme.Holo.NoActionBar như được mô tả here, vì [tiếc là] màn hình giật gân của tôi sử dụng số ActionBar.

Trong khi đó, các ứng dụng mà không mở rộng Application lớp không hiển thị màn hình trắng lúc khởi động.

Điều này lý tưởng là các khởi tạo được thực hiện trong đối tượng Application cần phải xảy ra trướcActivity đầu tiên được hiển thị. Vì vậy, câu hỏi của tôi là, làm thế nào tôi có thể thực hiện các khởi tạo này khi khởi động ứng dụng mà không cần sử dụng đối tượng Application? Có thể sử dụng một số Thread hoặc Service, tôi cho là như vậy?

Đây là một vấn đề thú vị để suy nghĩ. Tôi không thể bỏ qua nó theo cách thông thường (bằng cách thiết lập các chủ đề NoActionBar), như tragically màn hình Splash của tôi thực sự có một ActionBar do một số lý do không liên quan.

Lưu ý:

tôi đã giới thiệu đến các câu hỏi sau:

Tài liệu tham khảo:

+1

Bạn đã tìm thấy vấn đề, bạn đang làm nhiều init trong ngữ cảnh ứng dụng, chặn tải hoạt động, cố gắng không đồng bộ hóa hoạt động này, cho phép hoạt động tải hiển thị cho đến khi một số chuỗi kết thúc. – AxelH

+0

[This] (http://stackoverflow.com/questions/35054872/how-to-pre-load-mainactivity-in-splashactivity-so-there-would-be-no-delay-when-l) có thể giúp – Max

+0

Bạn đã nhìn vào tải chậm? Tôi tin rằng bạn đang đi đúng hướng với các dịch vụ không nằm trên chuỗi chính. –

Trả lời

42

Vấn đề với nền trắng được gây ra do sự khởi đầu lạnh android trong khi tải ứng dụng vào bộ nhớ, và nó có thể thể tránh được với điều này:

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

bố trí

<?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 mặt

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

Thêm chủ đề này để Splashscreen của bạn trong manifest

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

đó sẽ sản xuất efect như thế này

a busy cat

để biết thêm chi tiết và giải pháp nhiều hơn bạn có thể kiểm tra điều này BlogPost

+0

nó đã không giúp màn hình trắng và hoạt hình ở cuối –

+0

Đây là thực hiện thẳng về phía trước. Có thể có một số phần khác của mã của bạn gây ra sự cố. Vui lòng mở một câu hỏi khác và il ở đó để giúp bạn :) –

+0

Tôi đã giải quyết vấn đề này bằng cách làm động giữa các chủ đề và thay đổi chủ đề mà không thể vẽ được mà chỉ có màu sau và sau đó trên onWindowFocusChanged() làm nổi bật nội dung và hoạt ảnh khác khôn ngoan của tôi whited xuống giữa quá trình chuyển đổi là tốt. hoạt hình của các chủ đề đã giúp rất nhiều –

12

Trước hết, để loại bỏ các màn hình trắng đọc - https://www.bignerdranch.com/blog/splash-screens-the-right-way/

Nhưng quan trọng hơn, tối ưu hóa tải ban đầu của bạn và trì hoãn bất kỳ công việc nặng nhọc để khi bạn có thời gian để chạy nó. Đăng lớp ứng dụng của bạn ở đây nếu bạn muốn chúng tôi xem xét nó.

+0

nhờ liên kết tuyệt vời – Redman

1

Bạn đã cố gắng đặt khởi tạo thành onActivityCreated?

Bên Application lớp:

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

      } 
     }); 
1

Như bạn đã biết lý do tại sao màn hình trắng này là có, như do quá trình nền hoặc ứng dụng khởi tạo hoặc các tập tin lớn, do đó chỉ cần kiểm tra dưới đây ý tưởng cho vượt qua từ này.

Để ngăn màn hình trắng này ở đầu ứng dụng, một cách là màn hình giật gân, đây chỉ là cách không phải là cuối cùng và bạn phải sử dụng.

Khi nào bạn sẽ hiển thị màn hình splash từ file splash.xml của bạn, sau đó cũng vấn đề này sẽ được duy trì cùng,

Vì vậy, bạn phải tạo phong cách ont trong tập tin style.xml cho màn hình và ở đó bạn phải đặt nền cửa sổ làm hình ảnh giật gân của bạn và sau đó áp dụng chủ đề đó cho hoạt động giật gân của bạn từ tệp kê khai. Vì vậy, bây giờ khi bạn sẽ chạy ứng dụng, đầu tiên nó sẽ thiết lập chủ đề và bằng cách này người dùng sẽ có thể nhìn thấy hình ảnh trực tiếp giật gân thay vì màn hình trắng.

5

Trong vòng phương thức gọi lại vòng đời, bạn có thể khai báo hoạt động của bạn hoạt động như thế nào khi người dùng rời khỏi và nhập lại hoạt động. Hãy nhớ rằng cách Android được thiết kế, có một vòng đời cho mỗi và mọi ứng dụng. Nếu bạn đặt quá nhiều tải vào phương pháp onCreate() (là phương pháp được sử dụng để tải các tệp bố cục và initalise bất kỳ điều khiển nào bạn có trong đó), thì màn hình trắng sẽ hiển thị rõ hơn, vì tệp bố cục sẽ mất nhiều thời gian hơn để tải.

Tôi khuyên bạn nên sử dụng một số phương pháp khác nhau khi bắt đầu một hoạt động. Như vậy là onStart() (được gọi là điều đầu tiên khi ứng dụng được tải), onActivityCreated() (được gọi sau khi bố cục được hiển thị và hữu ích nếu bạn đang thực hiện bất kỳ xử lý dữ liệu nào khi bắt đầu hoạt động).

Để làm cho nó dễ dàng hơn cho bạn, dưới đây là sơ đồ vòng đời hoạt động chính thức:

enter image description here

+0

Cảm ơn câu trả lời của bạn, nó rất thú vị. Tuy nhiên, tôi tin rằng bạn hiểu lầm câu hỏi của tôi. Vấn đề không phải do các khởi tạo trong 'Hoạt động' đầu tiên, mà là do các đối tượng trong đối tượng' Application' toàn cầu gây ra. Và tôi không tin rằng tôi có thể áp dụng những mối quan tâm như vậy ở đó, bởi vì không giống như 'Activity', nó chỉ có một phương thức' onCreate() '. –

+0

Tại sao bạn mở rộng lớp ứng dụng chứ không phải lớp hoạt động? –

+0

Được rồi, vậy nghĩa là tôi nên bỏ hoàn toàn đối tượng 'Application' và chuyển tất cả mã khởi tạo sang' Hoạt động' đầu tiên ... –

4

Bạn đã cố gắng thiết lập các thuộc tính android:windowBackground trong chủ đề của hoạt động phóng của bạn, hoặc là một màu hoặc có thể vẽ?

Ví dụ này:

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

khi thêm vào chủ đề hoạt động Launcher sẽ hiển thị một màu đen (chứ không phải là màu trắng) khi khởi động. Đây là một mẹo dễ dàng để ẩn khởi tạo lâu dài, trong khi hiển thị cho người dùng của bạn một cái gì đó, và nó hoạt động tốt ngay cả khi bạn phân lớp đối tượng Ứng dụng.

Tránh sử dụng các cấu trúc khác (kể cả Chủ đề) để thực hiện các tác vụ khởi tạo lâu dài, vì bạn có thể không thể kiểm soát vòng đời của các cấu trúc như vậy. Đối tượng Application là nơi chính xác để thực hiện chính xác kiểu hành động này.

20

xin thêm dòng này vào chủ đề ứng dụng của bạn

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

Nó làm gì? –

+0

Nó hoạt động cho tôi !! –

+0

hoạt động như một sự quyến rũ! – Amare

2

Cả hai thuộc tính làm việc

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

Chỉ cần viết các mục trong giá trị/styles.xml:

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

Ví dụ, trong 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> 
1

Tôi gặp vấn đề tương tự, bạn phải cập nhật kiểu của mình.

kiểu.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> 

Tệp kê khai của bạn sẽ trông giống như dưới đây.

<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

Hy vọng điều này sẽ giúp bạn.

0

Tôi khuyên bạn nên xem câu trả lời được cung cấp tại this page. Giải quyết bằng cách sử dụng thuộc tính Style. Nó không làm phiền người dùng.

Các vấn đề liên quan