Android 12 启动画面

从 Android 12 开始,在所有应用的冷启动和温启动期间,系统一律会应用 Android 系统的默认启动画面。默认情况下,此系统默认启动画面由应用的启动器图标元素和主题的 windowBackground(如果是单色)构成。

也就是说,只要你的应用运行在Android 12的系统上,都会受到影响,以支付宝为例,截止到2023-01-24日,在Android 13的系统上冷启动时,可以很明显的看到会出现一个闪屏页,页面中间会显示一个启动图标。这个就是受到了系统影响,没有做适配。

Google应该是想让Android有一个统一的启动风格,但是讲道理推出的有点太晚了,国内的App启动页不仅仅是个简单的展示,有的还要显示广告,且风格也各不相同,都有自己的一套启动ui,所以,推出这个splashscreen对国内的app完全是个负担。
但是不适配的话启动的时候看起来有很怪,会出现两个闪屏页,所以,还是要硬着头皮适配一下。

SplashScreen适配

适配方法也很简单,按照官方文档的步骤来即可。
官方建议我们使用AndroidX中的SplashScreen库,该库使用 SplashScreen API,能够向后兼容,官方宣称可在所有 Android 版本上显示外观和风格一致的启动画面。

但是实际使用并非如此,例如动画在Android 12 以下的系统上不生效,如果需要动画,可自己使用其他方式实现,如果只是显示一个图片,那么就不受影响。

以下是适配步骤

将compileSdkVersion更改为31或以上

compileSdkVersion 31

添加依赖

implementation 'androidx.core:core-splashscreen:1.0.0'

准备启动页面要显示的图片或者动画

新增主题

    <style name="Theme.App.SplashScreen" parent="Theme.SplashScreen"><!--背景颜色--><item name="windowSplashScreenBackground">@color/white</item><!--设置动画或图片,注意动画在Android12 以下不生效 很难受...--><item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash</item><!--动画执行时间--><!--        <item name="windowSplashScreenAnimationDuration">1000</item>--><!--设置闪屏也后启动页面的主题 说白了 就是app本来的主题--><item name="postSplashScreenTheme">@style/Theme.XeonYuTheme</item></style>

创建启屏页面 SplashActivity
先指定页面的主题

然后就是代码了,代码非常简单,如果你没有其他需求,直接在oncCreate中调用 installSplashScreen() ,然后正常跳转页面即可.

class SplashActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)/*setContentView 可不写*/
//        setContentView(R.layout.activity_splash)/*创建与页面关联的SplashScreen实例*/installSplashScreen()/*跳转页面*/val intent = Intent(this, MainActivity::class.java)startActivity(intent)}
}

然后运行看看

可以看到,启屏页就ok了,非常简单。

在启动屏幕页面显示弹窗

一般情况下,我们需要在用户首次打开app时弹窗让用户同意隐私协议,以及做一些初始化操作之类的。那这种情况下,如要用户点击同意后再进行跳转。

此时,我们可以使用setKeepOnScreenCondition 配合 setOnExitAnimationListener,示例代码如下


class SplashActivity : AppCompatActivity() {/*** 控制是否保持启动页面的变量,值为false时继续往下走*/private val keepOnScreenCondition = AtomicBoolean(true)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)/*setContentView 可不写*/
//        setContentView(R.layout.activity_splash)/*创建与页面关联的SplashScreen实例*/installSplashScreen().apply {/*保持住启动页面的显示*/setKeepOnScreenCondition {keepOnScreenCondition.get()}/*指定是否Activity要自己处理启动画面动画 实际上就是keepOnScreenCondition的值为false时这个就会回调*/setOnExitAnimationListener {/*在这里我们可以弹窗让用户同意隐私政策*/val alertDialog = AlertDialog.Builder(this@SplashActivity).setTitle("隐私协议").setMessage("隐私协议内容").setPositiveButton("同意") { dialog, which ->/*跳转页面*/val intent = Intent(this@SplashActivity, MainActivity::class.java)startActivity(intent)}.setNegativeButton("拒绝") { dialog, which ->this@SplashActivity.finish()}.create();alertDialog.show();}}MainScope().launch {Log.i("SplashActivity", "可以做一些初始化逻辑")delay(500)keepOnScreenCondition.compareAndSet(true, false)}}
}

再来运行看看:

部分设备debug模式下setOnExitAnimationListener不回调的问题

美滋滋的写完代码后,以为没啥问题了,结果换了个Android12的真机运行后发现一直卡在启动页,并没有弹窗或者跳转页面,试了好多次依旧如此。
加了log发现setOnExitAnimationListener中的回调没有执行。明明是按照官方文档写的,怎么会有问题呢?
仔细看了下文档说是要保证在splashscreen退出前setOnExitAnimationListener,这个我代码是肯定没问题的。

后来手动把app杀死,然后点击图标手动启动时又是正常的,给我整懵了,于是查了下资料发现其他人也遇到了这种问题。

https://issuetracker.google.com/issues/197906327

这个问题被google官方人标记为是预期的,不会解决,解释如下:

意思就是:
这个是有意这样的,因为IDE实际上使用Instrumentation来打开应用程序,所以系统将其解释为一个应用程序打开另一个应用程序,而不是用户单击启动器图标。
所以会出现setOnExitAnimationListener不执行的情况。

除了debug时会受到影响,通过其他方式拉起App也会收到影响比如一些rom上安装后会自动打开App,这种就会卡住,必须杀掉进程后重新冷启动才能正常进去。
因此,我们需要做的就是即使 setOnExitAnimationListener 没有被回调,也要保证后续代码得到执行。

下面抛砖引玉,大体思路就是给最终被执行的方法加个标记,在 keepOnScreenCondition.compareAndSet(true, false) 之后延迟短暂的时间再去调用一下最终要执行的方法,以确保一定会得到执行。

示例代码如下:
伪代码

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.yzq.kotlincommon.ui.activity.MainActivity
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBooleanclass SplashActivity : AppCompatActivity() {/*** 控制是否保持启动页面的变量,值为false时继续往下走*/private val keepOnScreenCondition = AtomicBoolean(true)/*最终的方法是否调用*/private val dialogShowInvoke = AtomicBoolean(false)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)/*setContentView 可不写*/
//        setContentView(R.layout.activity_splash)/*创建与页面关联的SplashScreen实例*/installSplashScreen().apply {/*保持住启动页面的显示*/setKeepOnScreenCondition {keepOnScreenCondition.get()}/*指定是否Activity要自己处理启动画面动画 实际上就是keepOnScreenCondition的值为false时这个就会回调*/setOnExitAnimationListener {/*在这里我们可以弹窗让用户同意隐私政策*/showDialog()}}MainScope().launch {Log.i("SplashActivity", "可以做一些初始化逻辑")/*解除blockui,此时正常情况下会调用setOnExitAnimationListener 已知Android12拉起App时不会调用*/keepOnScreenCondition.compareAndSet(true, false)delay(100)//这里最好延迟一下,保证setOnExitAnimationListener有机会得到执行if(!dialogShowInvoke.get()){showDialog()//这里去掉调用一下最终要执行的方法,兜个底}}}@Synchronizedprivate fun showDialog() {if (dialogShowInvoke.get()) {/*已经执行了*/return}dialogShowInvoke.compareAndSet(false, true)val alertDialog = AlertDialog.Builder(this@SplashActivity).setTitle("隐私协议").setMessage("隐私协议内容").setPositiveButton("同意") { dialog, which ->/*跳转页面*/val intent = Intent(this@SplashActivity, MainActivity::class.java)startActivity(intent)}.setNegativeButton("拒绝") { dialog, which ->this@SplashActivity.finish()}.create();alertDialog.show()}
}

这样我们就能够确保启动时不会卡住,但是在Android12上被其他app调起会出现设置的UI显示不正常的情况,比较影响观感,暂时还没想到好的办法,有知道怎么弄的大佬可以指点一波。


如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

适配splashscreen步骤以及启动卡住不动(白屏)的坑相关推荐

  1. android应用启动页面显示不出来了,Android应用中启动页出现白屏如何解决

    Android应用中启动页出现白屏如何解决 发布时间:2020-12-11 14:41:17 来源:亿速云 阅读:100 作者:Leah 今天就跟大家聊聊有关Android应用中启动页出现白屏如何解决 ...

  2. android 7.0 黑屏,Android app启动是出现白屏或者黑屏如何解决?

    1.为什么 APP 启动时会出现白屏或者黑屏? 当打开一个 Activity 时,如果这个 Activity 所属的应用还没有在运行,系统会为这个 Activity 所属的应用创建一个进程,但进程的创 ...

  3. Android APP启动时出现白屏或者黑屏怎么办?

    1.为什么APP启动时会出现白屏或者黑屏? 当打开一个Activity时,如果这个Activity所属的应用还没有在运行,系统会为这个Activity所属的应用创建一个进程,但进程的创建与初始化都需要 ...

  4. android打开app白色页面,完美解决Android App启动页有白屏闪过的问题

    应用启动的时候有短暂的白屏,如图: 可以通过设置theme的方式来解决 @color/colorPrimary @color/colorPrimaryDark @color/colorAccent t ...

  5. nwjs解决页面透明化,启动时显示白屏的问题

    nwjs解决页面透明化,启动时显示白屏的问题 参考文章: (1)nwjs解决页面透明化,启动时显示白屏的问题 (2)https://www.cnblogs.com/jinling/p/6068918. ...

  6. flutter应用启动页面-防白屏

    android应用程序自己本身会带有一定时间的启动页面白屏,在flutter上貌似就更长时间的白屏了,分享一下如何解决: 首先我们看到官方文档有类似的相关介绍,其实官方给我们也提供了一定程度上的解决办 ...

  7. app启动会闪白屏,怎么处理?

    我在做一个app应用的时候,发现启动该应用会出现几秒的白屏,然后再渲染界面.有以下两个方面的原因:第一,欢迎页启动的时候加载请求的数据量过大,导致欢迎页在出现之前页面上有一个短暂的白色闪屏停留.但是我 ...

  8. apk很小 白屏时间长_小精灵启动后会白屏很久

    我这边也是一样的情况,几百个手机不开wifi会白屏然后闪退.打开wifi就能开了.就算不连wifi只是打开wifi就可以打开小精灵. 希望尽快修复. 闪退日志是: 2016-10-31-14-45-3 ...

  9. linux强制关机启动后是白屏,解决安装Ubuntu后,启动出现屏幕空白(全黑,无内容)...

    洒家闲来无事,想起原来曾经遇到过在笔记本上直接安装ubuntu出现过启动屏幕空白,无法继续安装的问题,因此这次打算来进行解决. 首先查了一下网上的资料,找到两帖. 第一帖:http://epheien ...

最新文章

  1. 浅谈分布式计算的开发与实现(一)
  2. maven 不编译jasper文件_第一个SpringBoot项目、核心配置文件properties(yml、yaml)、集成jsp...
  3. mysql可以使用dataguard_逻辑DataGuard的配置
  4. 200919阶段一C++STL容器
  5. Highcharts使用=====通过指定日期显示曲线
  6. jmeter的如何设置headers
  7. JVM内存模型及分区
  8. 这篇文章写给想学计算机视觉还没开始的人
  9. 微信小程序之input前加图标
  10. 区块链相关技术学习总结(1)——区块链以及区块链技术入门详解
  11. WARNING: A newer version of conda exists
  12. 八年级作文-断了的弦
  13. 导数的四则运算法则_胡昉祖《导数的概念》和《定积分》
  14. 提个醒。阿里内网最新发布“M8”级Java面试笔记,助力金三银四
  15. 【计算机使用技能积累】双系统卸载Ubuntu,释放磁盘并合并分区
  16. python计算机视觉--全景图像拼接
  17. 支持电竞比分实时查询的软件~和比分网之间的对比
  18. vue-cli3,虾皮java开发面经
  19. Stereogram(极射赤面)投影--主要用于中高纬和极区的天气图
  20. 计算机系统中常用的进制,计算机中常用 二进制 八进制 十进制 十六进制的特点...

热门文章

  1. python如何把八进制转换成十进制_Python练习实例82 | 八进制数如何转化为十进制数?...
  2. 解决帝国时代2终极版闪退问题
  3. java 成员变量调用其他类方法6_方法内部类中不能访问外部类的成员变量。
  4. JAVA 计算两个日期间的时间间隔
  5. nginx配置图片跨域访问
  6. LCD1602的学习和实验(基于蓝桥杯单片机)
  7. linux上报错xxxxxxx.jar中没有主清单属性
  8. 一文了解MVI架构,学起来吧~
  9. 很多人问我用屏蔽网线为什比非屏蔽的网线干扰会更大?
  10. 【数据结构】栈和队列OJ练习(栈和队列相互实现+循环队列实现)