现象
App启动时进入启动页时出现白屏页,然后大概一秒之后就出现了背景图片。
原因
用户点击Launcher界面的APP图标到展示真正的Activity界面需要一个启动时间,因为这启动时间因APP而异,系统为了避免造成卡顿的误会,系统进程在创建Application的过程中会产生一个BackgroudWindow,系统首先会读取当前Activity的Theme,然后根据Theme中的配置来绘制,当Activity加载完毕后,才会替换为真正的界面这个时候加载的是windows背景,所以开始的黑屏/白屏就是windows的背景颜色,因此我们只要在启动页设置windows背景颜色就好了,那么在哪里设置呢? 就是theme里面。
解决方案一 : windowBacground置为透明
当用户点击APP时,系统会自动把windowBacground置为透明的,看到系统当前的Launcher界面,容易造成点击了APP后没有响应的误解,还有适配android8.0的时候在 values-v26中,取消android:windowIsTranslucent属性
解决方案二 : 定义Activity的Style
layer_splash通过layer-list来实现图片的叠加,让开发者可以自由组合。其中属性android:opacity=”opaque”是为了防止在启动的时候出现背景的闪烁,你也可以使用其他Drawable资源
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<item android:drawable="@color/color_D0021B" />
<item
android:top="200dp"
android:drawable="@drawable/ic_logo"
android:gravity="top|center_horizontal" />
</layer-list>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!--将用于配置到特定的Activity上的样式-->
<style name="SplashStyle" parent="AppTheme">
<item name="android:windowBackground">@drawable/layer_splash</item>
</style>
</resources>
需要注意一定是Activity的Theme,而不是Application的Theme
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xys.startperformancedemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:theme="@style/SplashStyle">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
在Activity加载真正的界面之前,将THEME还原回正常的THEME
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);//还原回正常的Theme
super.onCreate(savedInstanceState);
SystemClock.sleep(2000);
setContentView(R.layout.activity_main);
}
}
启动的时候,系统会先展示一个画面,这个画面就是系统解析到的Style,等Activity加载完全完毕后,才会加载Activity的界面,而在Activity的界面中,我们将主题重新设置为正常的主题,从而达到一个友好的启动体验,这种方式其实并没有真正的加速启动过程,而是通过交互体验来优化了展示的效果。其实以上两种方式的核心思想都是差不多的:替换系统预定义的样式,所以也可以替换很多其他的属性来实现具体的UI效果