Android基础篇 APP启动出现白屏问题

news/2024/11/14 18:37:00/

一、问题描述

当打开一个Activity时,如果这个Activity所属的应用还没有在运行,系统会为这个Activity所属的应用创建一个进程(冷启动),但进程的创建与初始化都需要时间,在这个动作完成之前系统要做什么呢?

如果没有任何反应的话,如果程序初始化的时间很长,用户可能还以为没有点到相应的位置。

但此时所启动的程序还没初始化完,既无法显示程序,又不能停在原处不做任何动作,怎么办?这就有了Starting Window的概念,也可以称之为Preview Window。

二、问题原因

Starting Window就是一个用于在应用程序进程创建并初始化成功前显示的临时窗口,拥有的Window Type是TYPE_APPLICATION_STARTING。在程序初始化完成前显示这个窗口,以告知用户系统已经知道了他要打开这个应用并做出了响应,当程序初始化完成后显示用户UI并移除这个窗口。

显示白屏或者黑屏,是由你的启动Activity或者Application来决定的。

如果你使用的是Light主题,那么就可能出现白屏

如果你使用的是Black主题,那么就可能出现黑屏

当你设置Light或者Black主题时,Starting Window显示的就是你启动Activity的android:windowBackground属性,所以才会出现白屏或者黑屏的情况。

三、解决方案

方案一:

(1)在style.xml文件中为启动的Activity设置主题,设置android:windowBackground属性为启动Activity显示的闪屏图片,这样才有APP秒开的效果。

设置android:windowFullscreen属性为true,使闪屏图片全屏显示

设置windowNoTitle属性为true,隐藏Activity的ActionBar显示。

<!-- 防止欢迎页白屏或者黑屏,设置图片 -->
<style name="SplashTheme" parent="AppBaseTheme"><item name="android:windowBackground">@drawable/img_welcome</item><item name="android:windowFullscreen">true</item><item name="windowNoTitle">true</item><!--<item name="android:windowIsTranslucent">false</item>--><!--<item name="android:windowDisablePreview">true</item>-->
</style>

(2)在清单文件AndroidManifest.xml中,为启动的Activity设置主题SplashTheme。

<activityandroid:name=".ui.WelcomeActivity"android:theme="@style/SplashTheme"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
</activity>

方案二:

此外,如果设置android:windowIsTranslucent属性,表明该窗口是半透明的,这样也不会出现白屏或者黑屏。

但是,它和MainActivity的显示是同步,如果在MainActivity启动的时候,有过多复杂的操作,就会出现在手机中点击了应用程序的图标之后,但过两秒才会打开应用程序不好的卡顿体验效果

方案三:

如果设置android:windowDisablePreview属性,禁用窗口的预览动画, 在MainActivity显示之前,系统永远不会使用窗口的主题来显示它的预览,这也保证了不会出现白屏或者黑屏。

但是,与设置android:windowIsTranslucent属性一样,如果在MainActivity启动的时候,有过多复杂的操作,就会出现在手机中点击了应用程序的图标,但过两秒才会打开应用程序不好的卡顿体验效果

其他方案:

以上方式可以实现APP秒开,但是我不想显示一张图片,那么你也可以显示纯颜色,或者纯颜色加小图标。

Starting Window显示纯颜色,直接设置android:windowBackground属性为颜色代码:

<item name="android:windowBackground">@color/colorAccent</item>

Starting Window显示纯颜色加图标,需要在Drawable中定义一个splash.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"><!-- 背景颜色 --><item android:drawable="@color/green" /><item><!-- 图片 --><bitmapandroid:gravity="center"android:src="@drawable/icon_welcome" /></item>
</layer-list>
<!-- 防止欢迎页白屏或者黑屏,设置图片 -->
<style name="SplashTheme" parent="AppBaseTheme"><item name="android:windowBackground">@drawable/splash</item><item name="android:windowFullscreen">true</item><item name="windowNoTitle">true</item>
</style>

四、拓展

(1)Activity和AppCompatActivity

继承自Activity的不带标题栏,继承自AppCompatActivity的会带标题栏

Android Support Library(安卓兼容包)是为了构件一个可以跑在不同版本Android平台的软件。

重构AppCompat在新的AppCompat中,加入主题色,Toolbar等功能。在新版本中推荐使用AppCompatActivity代替ActionBarActivity。

(2)App的冷启动与热启动

1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。

2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

(3)特点

1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。

(4)App启动的过程

1.点击桌面图标,Launcher会启动程序默认的Acticity,之后再按照程序的逻辑启动各种Activity

2.启动Activity都需要借助应用程序框架层的ActivityManagerService服务进程(Service也是由ActivityManagerService进程来启动的);

在Android应用程序框架层中,ActivityManagerService是一个非常重要的接口

它不但负责启动Activity和Service,还负责管理Activity和Service。

①. 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;

②. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息;

③. ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,

而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;

④. ApplicationThread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;

⑤. 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,

因为新的Activity就在原来的Activity所在的进程中进行启动;

⑥. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口,通知相应的进程执行启动Activity的操作;

⑦. ApplicationThread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。


http://www.ppmy.cn/news/563669.html

相关文章

Android-彻底解决启动白屏、跳转页面白屏!

背景&#xff1a;项目在启动页面老是有一瞬间白屏&#xff0c;还有切换日夜间模式时finish栈内所有Activity再启动MainActivity时会白屏。 1. 初步解决办法: 设置窗口的背景色为启动页。 虽然看不到白屏了&#xff0c;但还是有点丑&#xff0c;怪怪的… <style name"…

Android 8.0系统以上手机启动白屏-因为权限问题的解决方案

同样的代码在8.0以下手机上运行无误&#xff0c;但是8.1以及9.0的用户反馈启动白屏。这就奇怪了&#xff0c;我首先断点调试没有发现问题&#xff0c;最后多打了几个断点发现在获取设备信息时抛异常了&#xff0c;断点卡在下面两行。 String device_type android.os.Build.MO…

python闭包和装饰器

目录 一、闭包 1.简单演示 2.内函数修改外函数变量问题 二、装饰器 1.基础使用 2.通用装饰器 3.多个修饰器引用 4.装饰器传参 三、类装饰器 1.callable()和__call__ 2.类装饰器的简单使用 结语 一、闭包 1.简单演示 条件 在函数嵌套&#xff08;函数里面在定义函…

沧州市新华区小赵庄乡社工站幸福院护蕾驿站微项目启动

烈日炎炎&#xff0c;难抵群众热情。6月16日上午&#xff0c;小赵庄乡社工站在蔡庄子社区开展社工站微项目启动仪式暨助老文艺展演活动。市民政局慈善社工科科长罗向凯&#xff0c;新华区民政局局长李瑞勇&#xff0c;新华区小赵庄乡书记徐晋等人出席本次活动。 社工站护蕾驿站…

jpcsp源码解读9:指令的抽象描述与指令的译码

本文尝试说明jpcsp中译码器单元的实现方式。 / 首先是对指令的一个抽象描述&#xff0c;Instruction类&#xff1a; public static abstract class Instruction / java科普&#xff1a; 注意这是一个抽象类&#xff0c;不可以被实例化。只有在其某个子类中实现该抽象类中…

用Lucene的SpellChecker实现Google的“您是不是要找”功能

引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff08;弗洛伊德的全名 Sigmund Freud&#xff09;、不小心写错字母&#xff08;Sinpsons…

wang----- 用Java实现Google的“您是不是要找”功能

文章来源&#xff1a;http://blog.csdn.net/haydenwang8287/article/details/5777112 引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff…

用Java实现Google的“您是不是要找”功能

引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff08;弗洛伊德的全名Sigmund Freud&#xff09;、不小心写错字母&#xff08;Sinpsons&a…