Android splash page startup optimization full analysis

question

Generally, there is no special treatment. When android starts, there will be a white screen or a black screen, and the experience is very poor. The reason is that the white screen is when the app is initialized when it is cold started, and the system automatically fills the screen with the default background color. This default background color is related to the app theme you define. For example, if your theme inherits from Theme.AppCompat.Light.NoActionBar, it will be white at startup.

This chapter will solve the problem of slow app startup.

solve

As far as I know, there are generally two ways to solve this problem:

  1. Change this background color to transparent. Although it seems that there is no white screen, after the user clicks on the app, the original white screen becomes the desktop background, which makes people feel that the slow startup is the fault of the mobile phone system and has nothing to do with the app. It's a bit of a throwaway.

    The specific method is styleto add the theme in

    <style name="AppTheme.SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>
    

    Note that this windowIsTranslucentproperty is the key code to set the background color transparency. Then set the AndroidManifestone that started as this theme inactivitytheme

    <activity
            android:name=".ui.base.SplashActivity_"
            android:theme="@style/AppTheme.SplashTheme">
    
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
    </activity>
  2. The first method is just to give the user an illusion, "It's a problem with your mobile phone system, not my app." Since I can change the background to be transparent, why can't I directly change it to the background image of my splash page, so I use this background image first when the screen is blank. When the splash page is loaded, it will be seamlessly connected. But what the user sees is, "Yes, this is very fast, click without any pause, start immediately.".

    For the specific method, just AppTheme.SplashThemechange the properties of the one just now.

    <style name="AppTheme.SplashTheme" parent="@android:style/Theme.Light.NoTitleBar.Fullscreen">
        <item name="android:windowBackground">@drawable/splash</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>

    Here windowBackgroundis the key code for setting the background image. During the cold start time, the screen is set to this image. The next use is the same, AndroidManifestyou can use it after registration. Highly recommended.

re-optimization

After the white screen problem is solved, let's take a look at the general app startup method using the splash page. Perhaps the most common method is to make the startup page an Activity, and jump to MainActivity after startup.

SplashActivity->MainActivity

But isn't this a bit of a waste? SplashActivityDuring running, the app should be able to do some initialization, load data, and reduce MainActivitythe burden. So SplashActivityyou don't need it. Splash can be dialogreplaced by full screen and destroyed directly when it is used up. This way, the app starts faster. After loading splash, MainActivitythe data page is loaded.

Here is a packaged implementation: SplashDialog


public class SplashScreen {

    private Dialog splashDialog;
    private Activity activity;

    public SplashScreen(Activity activity) {
        this.activity = activity;
    }

    /**
     * 显示splash图片
     *
     * @param millis        停留时间 毫秒
     * 
     */
    public void show(final int millis) {
        Runnable runnable = new Runnable() {
            public void run() {
                DisplayMetrics metrics = new DisplayMetrics();

                final ImageView root = new ImageView(activity);
                root.setMinimumHeight(metrics.heightPixels);
                root.setMinimumWidth(metrics.widthPixels);
                root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
                root.setScaleType(ImageView.ScaleType.FIT_XY);

                   //glide加载图片
                GlideApp.with(activity)
                        .load(URL_SPLASH_IMAGE)
                        .placeholder(R.drawable.splash)
                        .error(R.drawable.splash)
                        .diskCacheStrategy(DiskCacheStrategy.NONE)
                        .into(root);

                splashDialog = new Dialog(activity, android.R.style.Theme_NoTitleBar_Fullscreen);

                Window window = splashDialog.getWindow();
                window.setWindowAnimations(R.style.dialog_anim_fade_out);

                splashDialog.setContentView(root);
                splashDialog.setCancelable(false);
                splashDialog.show();

                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    public void run() {
                        removeSplash();
                    }
                }, millis);
            }
        };
        activity.runOnUiThread(runnable);
    }

    private void removeSplash() {
        if (splashDialog != null && splashDialog.isShowing()) {
            splashDialog.dismiss();
            splashDialog = null;
        }
    }
}

Here I use glide to load images, you can also change to your own loading tool.

After MainActivityusing and oncreatecalling directly after, the new SplashDialog(this).show(3000);
startup page becomes just one line of code, and it is faster and more convenient. ps: Don't forget to MainActivityadd the previous topic to .

Step on the pit

The second method mentioned above is to set the background image. There is a pit here, if you have similar problems, you can refer to it.

Mine MainActivityhas an immersive status bar, but not a transparent bottom navigation bar. As a result windowBackground, the height of the background image is set by adding the bottom navigation bar, that is to say, the navigation bar blocks part of the background image, but SplashDialogthe loaded image ignores the bottom navigation bar, so the two images will be misplaced and start up. When the image appears, the location moves a bit.

The solution is, in the previous AppTheme.SplashTheme, inherit from @android:style/Theme.Light.NoTitleBar.Fullscreen, that is, the old version of the theme, do not inherit from Theme.AppCompat.Light.NoActionBar. The reason is guessed that the old version does not support occupying the space of the navigation bar, and naturally it will not be blocked by the navigation bar.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325671420&siteId=291194637