如何在Android 12 SplashScreen中使用或选择退出

如何在Android 12 SplashScreen中使用或选择退出,android,splash-screen,android-12,Android,Splash Screen,Android 12,Android 12中的新API看起来不错,但与之前一样,文档中的示例代码并没有真正帮助解释整个正确的实现。也有一些情况下,您可能会在启动屏幕期间执行一些任务,在我们的情况下,这是启动Firebase Auth,因此最好的方法可能只是选择退出使用此新的特色API,但根据lint警告,这似乎是强制性的,没有办法选择退出 应用程序不应提供自己的启动屏幕 Android 12(API 31+)中启动的应用程序定义的启动屏幕, 应用程序的启动屏幕由系统和 应用程序不应该创建自己的,否则用户将看到两个 飞

Android 12中的新API看起来不错,但与之前一样,文档中的示例代码并没有真正帮助解释整个正确的实现。也有一些情况下,您可能会在启动屏幕期间执行一些任务,在我们的情况下,这是启动Firebase Auth,因此最好的方法可能只是选择退出使用此新的特色API,但根据lint警告,这似乎是强制性的,没有办法选择退出

应用程序不应提供自己的启动屏幕

Android 12(API 31+)中启动的应用程序定义的启动屏幕, 应用程序的启动屏幕由系统和 应用程序不应该创建自己的,否则用户将看到两个 飞溅屏幕。请检查SplashScreen类以检查 启动屏幕可以控制和定制

旧设备的向后兼容性如何,如何处理?是否有任何codelab项目可供使用和测试

  • 我们可以选择退出SplashScreen吗?
  • 看起来我们不能选择退出,因为Android团队正试图统一应用程序加载体验:

  • 如何使用它?
  • 如果你什么都不做,那么它将使用主题的
    windowBackground
    ,并在你的应用程序绘制第一帧后立即关闭启动程序图标

    有许多属性可以修改,如背景、图标等:

  • 如果我想让splash多待一会儿呢?就像获取本地数据库。
  • 您可以使用
    ViewTreeObserver.OnPreDrawListener
    &从您的
    viewmodel
    返回进行阻塞调用,前提是它已准备就绪

    活动:

    // My Launcher Activity
    class MainActivity : AppCompatActivity() {
    
        private val viewModel : JustDelayViewModel by viewModels()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val content: View = findViewById(android.R.id.content)
            content.viewTreeObserver.addOnPreDrawListener(
                object : ViewTreeObserver.OnPreDrawListener {
                    override fun onPreDraw(): Boolean {
                        // Check if the initial data is ready.
                        return if (viewModel.getIsReady()) {
                            // The content is ready; start drawing.
                            content.viewTreeObserver.removeOnPreDrawListener(this)
                            true
                        } else {
                            // The content is not ready; suspend.
                            false
                        }
                    }
                }
            )
        }
    
    }
    
    class JustDelayViewModel : ViewModel() {
    
        fun getIsReady(): Boolean {
            val result = viewModelScope.runCatching {
                runBlocking {
                    //do some blocking call check for Firebase result or something
                    delay(5000)
                }
                true //return the result
            }
            return result.isSuccess
        }
    }
    
    视图模型:

    // My Launcher Activity
    class MainActivity : AppCompatActivity() {
    
        private val viewModel : JustDelayViewModel by viewModels()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val content: View = findViewById(android.R.id.content)
            content.viewTreeObserver.addOnPreDrawListener(
                object : ViewTreeObserver.OnPreDrawListener {
                    override fun onPreDraw(): Boolean {
                        // Check if the initial data is ready.
                        return if (viewModel.getIsReady()) {
                            // The content is ready; start drawing.
                            content.viewTreeObserver.removeOnPreDrawListener(this)
                            true
                        } else {
                            // The content is not ready; suspend.
                            false
                        }
                    }
                }
            )
        }
    
    }
    
    class JustDelayViewModel : ViewModel() {
    
        fun getIsReady(): Boolean {
            val result = viewModelScope.runCatching {
                runBlocking {
                    //do some blocking call check for Firebase result or something
                    delay(5000)
                }
                true //return the result
            }
            return result.isSuccess
        }
    }
    
    您可以阅读更多信息:

    以补充对旧设备的支持

    新的
    windowSplashScreen*
    属性需要添加到
    res/values-v31/style.xml
    文件中

    然后,对于传统的splashscreen,它取决于应用程序的当前实现

    如果应用程序仅使用带有自定义
    windowBackground
    的启动主题,则无需执行任何操作,因为
    windowBackground
    不用于新的启动屏幕(仅当它是简单的颜色时)

    如果应用程序有一些可见的启动屏幕
    活动
    ,Android 12上将会有一个双启动屏幕。要解决此问题,应用程序可以迁移到
    windowBackground
    解决方案


    如果应用程序确实需要保持其启动屏幕活动,它可以更新布局以匹配Android 12上的系统启动屏幕和/或使用
    SplashScreen.setOnExitAnimationListener()

    是的,我以前读过这些,但是,我们将如何在支持旧设备的情况下处理这一问题?最好有一个codelab或示例项目来使用。这种更新并没有受到很多人的欢迎,因为还有一些人不喜欢使用闪屏,因为这对于其他情况来说是完全不必要的。太糟糕了,这是他们所做的,而不是让平台更稳定,行为更少碎片化。统一Android在技术上是不可能的。