子曰:温故而知新,可以为师矣。 《论语》-- 孔子
作为 性能优化
系列章节的第一篇
,我们就来说一说 Android 黑白屏
的历史由来以及如何解决。
一、APP的三种启动方式
1. 冷启动
:
- 程序从头开始,系统没有为该程序创建进程。一般场景:程序安装后的第一次启动 或者 应用程序被系统完全终止后再打开。
2. 热启动
:
- 程序任然驻留在内存中,只是被系统从后台带到了前台,因此程序可以避免对象重复初始化,加载布局和渲染。需要注意的是:如果程序的某些内存被系统清除了,则需要重新创建这些对象以响应热启动事件。
3. 暖启动
:
- 它包含热启动和冷启动一系列操作子集,比热启动的消耗稍微多一些。它与热启动最大的区别在于,它必须通过调用
onCreate()
方法开始重新创建活动,也可以从传递给onCreate()
方法中保存的实例状态中获得某些对象的恢复。
说完了 3
种启动方式,下面我们以 冷启动的流程
引出黑白屏的问题。
4. 冷启动流程
:
- 加载并启动 App。
- 启动后立即为该 App 显示一个空白窗口。
- 创建 App 进程(创建应用程序对象)。
- 创建主 Activity。
- 加载布局,绘制。
当系统加载并启动 App 时,需要耗费相应的时间,即使时间不到 1s,用户也会感觉到当点击 App 图标时会有 “延迟” 现象,为了解决这一问题,Google 的做法是在 App 创建的过程中,先展示一个空白页面,让用户体会到点击图标之后立马就有响应;而这个空白页面的颜色是根据我们在 AndroiMainfest
文件中配置的主题背景颜色来决定的,现在一般默认是白色。这也就是 黑白屏问题
的由来。
用户就是上帝,就是流量。既然有这样的问题,那么作为开发者,该如何解决这一个问题?
二、黑白屏解决方案
1. 修改AppTheme
:
在应用默认的 AppTheme
中,设置系统 “取消预览(空白窗体)” 为 true
,或者设置空白窗体为透明。
代码如下:
<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:windowDisablePreview">true</item>
<!--设置背景透明-->
<item name="android:windowIsTranslucent">true</item>
</style>
方案一的两者方式目标都是将 Theme 的背景改为透明,这样用户从视觉上就无法看出黑白屏的存在。此方式不推荐,这是逆着谷歌的思路来的,既然到现在谷歌都没有取消这个空白窗体,我们应该好好利用,以前这个可以算作是一个bug,现在基本上都被用来打广告了。
2. 自定义AppTheme
:
- 1.自定义继承 AppTheme 的主题:
// styles文件中自定义启动页主题theme
<style name="AppTheme.LaunchTheme">
<item name="android:windowBackground">@drawable/launch_layout</item>
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
// launch_layout 文件
<?xml version="1.0" encoding="utf-8"?>
<!--取代空白窗体
使用layer-list
背景是纯色,附上一张图片
好处是图片体积可以很小,初色在机型适配上有出色表现
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/holo_red_dark"></item>
<item android:top="150dp">
<bitmap android:gravity="top"
android:src="@mipmap/top_img"/>
</item>
</layer-list>
- 2.将启动的 Activity 的 theme 设置为自定义主题 :
// AndroidManifest.xml 文件中
<activity android:name=".SplashActivity"
android:theme="@style/AppTheme.LaunchTheme"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
我这边仿照的是网易云音乐的启动流程,可以看一下效果图:
这种方式从用户角度和开发角度都考虑到了,是一种很不错的方式,推荐使用。如果想要在其中加入什么动画,倒计时什么的,都可以在 SplashActiivty
中写入代码,也可以参考其他的 app,SplashActiivty
页面参考此写法,然后再跳转到 广告页面,加入什么三秒倒计时等等。
写在文末
纸上得来终觉浅,绝知此事要躬行。 《冬夜读书示子聿》-- 陆游
好了,关于 Android 黑白屏由来以及解决方案
就说完了,各位小伙伴可以在项目中使用此方式优化。