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:
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
style
to 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
windowIsTranslucent
property is the key code to set the background color transparency. Then set theAndroidManifest
one that started as this theme inactivity
theme
<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>
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.SplashTheme
change 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
windowBackground
is 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,AndroidManifest
you 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? SplashActivity
During running, the app should be able to do some initialization, load data, and reduce MainActivity
the burden. So SplashActivity
you don't need it. Splash can be dialog
replaced by full screen and destroyed directly when it is used up. This way, the app starts faster. After loading splash, MainActivity
the 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 MainActivity
using and oncreate
calling 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 MainActivity
add 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 MainActivity
has 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 SplashDialog
the 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.