Android - 防止开机白屏
Android - Prevent white screen at startup
众所周知,许多 Android 应用程序在第一个 Activity
成为焦点之前会非常短暂地显示白屏。在以下情况下会出现此问题:
Android 扩展全球 Application
class 和
在其中执行主要的初始化。 Application
对象总是在第一个 Activity
之前创建(这一事实可以
在调试器中观察到),所以这是有道理的。这就是我的案例延迟的原因。
Android 在初始屏幕前显示默认预览 window 的应用程序。
设置android:windowDisablePreview = "true"
显然在这里不起作用。我也不能按照 here 所述将启动画面的父主题设置为 Theme.Holo.NoActionBar
,因为 [不幸的是] 我的启动画面使用了 ActionBar
.
同时,不扩展 Application
class 的应用不会 在以下位置显示白屏启动。
事实是,理想情况下,在 Application
对象中执行的初始化需要在 在 显示第一个 Activity
之前发生。所以我的问题是,如何使用 Application
对象在没有 的应用程序启动 时执行这些初始化?我想可能使用 Thread
或 Service
?
这是一个值得思考的有趣问题。我无法以通常的方式绕过它(通过设置 NoActionBar
主题),不幸的是,由于一些不相关的原因,我的启动画面实际上有一个 ActionBar
。
注:
我已经提到了以下问题:
White background when Android app start up
Why there is a white screen appears for 1sec when starting to run the apps in Android?
参考文献:
首先,要删除白屏,请阅读此内容 - https://www.bignerdranch.com/blog/splash-screens-the-right-way/
但更重要的是,优化您的初始负载并将任何繁重的工作推迟到您有空的时候 运行。 Post 如果你想让我们看一下你的申请 class 这里。
您是否尝试过对 onActivityCreated
进行初始化?
里面 Application
class :
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if(activity.getClass().equals(FirstActivity.class) {
// try without runOnUiThread if it will not help
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
new InitializatioTask().execute();
}
});
}
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
因为您已经知道为什么会出现这个白屏,因为后台进程或应用程序初始化或大文件,所以只需检查下面的想法以克服这个问题。
要防止应用程序启动时出现白屏,一种方法是启动画面,这只是一种非最终方法,您必须使用。
当您从 splash.xml 文件中显示启动画面时,此问题也将保持不变,
所以你必须在 style.xml 文件中为启动画面创建 ont 样式,你必须在那里设置 window 背景作为你的启动图像,然后将该主题应用到你的启动画面 activity 来自清单文件。所以现在当你 运行 应用程序时,首先它会设置主题,这样用户将能够直接看到启动图像而不是白屏。
在生命周期回调方法中,您可以声明当用户离开并重新进入 activity 时您的 activity 的行为方式。请记住 Android 的设计方式,每个应用程序都有一个生命周期。如果您对 onCreate()
方法(这是用于加载布局文件并初始化其中的任何控件的方法)施加过多负载,那么白屏将变得更加明显,因为布局文件将占用加载时间更长。
我建议在启动 activity 时使用几种不同的方法。这些是 onStart()
(应用程序加载后首先调用),onActivityCreated()
(在显示布局后调用,如果您在启动 [=23 时进行任何数据处理,则很有用) =]).
为了方便大家,下面是官方的activity生命周期图:
白色背景的问题是由于android在应用程序加载到内存时冷启动引起的,可以通过以下方式避免:
public class OnboardingWithCenterAnimationActivity extends AppCompatActivity {
public static final int STARTUP_DELAY = 300;
public static final int ANIM_ITEM_DURATION = 1000;
public static final int ITEM_DELAY = 300;
private boolean animationStarted = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onboarding_center);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus || animationStarted) {
return;
}
animate();
super.onWindowFocusChanged(hasFocus);
}
private void animate() {
ImageView logoImageView = (ImageView) findViewById(R.id.img_logo);
ViewGroup container = (ViewGroup) findViewById(R.id.container);
ViewCompat.animate(logoImageView)
.translationY(-250)
.setStartDelay(STARTUP_DELAY)
.setDuration(ANIM_ITEM_DURATION).setInterpolator(
new DecelerateInterpolator(1.2f)).start();
for (int i = 0; i < container.getChildCount(); i++) {
View v = container.getChildAt(i);
ViewPropertyAnimatorCompat viewAnimator;
if (!(v instanceof Button)) {
viewAnimator = ViewCompat.animate(v)
.translationY(50).alpha(1)
.setStartDelay((ITEM_DELAY * i) + 500)
.setDuration(1000);
} else {
viewAnimator = ViewCompat.animate(v)
.scaleY(1).scaleX(1)
.setStartDelay((ITEM_DELAY * i) + 500)
.setDuration(500);
}
viewAnimator.setInterpolator(new DecelerateInterpolator()).start();
}
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="144dp"
tools:ignore="HardcodedText"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:alpha="0"
android:text="Hello world" android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
android:textColor="@android:color/white"
android:textSize="22sp"
tools:alpha="1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:alpha="0"
android:gravity="center"
android:text="This a nice text"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle.Inverse"
android:textSize="20sp"
tools:alpha="1"
/>
<Button
android:id="@+id/btn_choice1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:scaleX="0"
android:scaleY="0"
android:text="A nice choice"
android:theme="@style/Button"
/>
<Button
android:id="@+id/btn_choice2"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:scaleX="0"
android:scaleY="0"
android:text="Far better!"
android:theme="@style/Button"
/>
</LinearLayout>
<ImageView
android:id="@+id/img_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/img_face"
tools:visibility="gone"
/>
</FrameLayout>
img 脸
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:drawable="?colorPrimary"/>
<item>
<bitmap
android:gravity="center"
android:src="@drawable/img_face"/>
</item>
将此主题添加到清单中的启动画面
<?xml version="1.0" encoding="utf-8"?>
<resources>
<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:windowBackground">@null</item>
</style>
<style name="AppTheme.CenterAnimation">
<item name="android:windowBackground">@drawable/ll_face_logo</item>
</style>
会产生这样的效果
有关更多详细信息和更多解决方案,您可以查看此
BlogPost
您是否尝试过将启动器 activity 主题中的 android:windowBackground
属性设置为颜色或可绘制对象?
例如:
<item name="android:windowBackground">@android:color/black</item>
添加到启动器后 activity 主题将在启动时显示黑色(而不是白色)。这是隐藏长初始化的简单技巧,同时向用户展示一些东西,并且它工作正常,即使你将 Application 对象子类化。
避免使用其他构造(甚至是线程)来执行长时间的初始化任务,因为您最终可能无法控制此类构造的生命周期。 Application 对象是执行此类操作的正确位置。
请将此行添加到您的应用主题中
<item name="android:windowDisablePreview">true</item>
更多信息:https://developer.android.com/topic/performance/vitals/launch-time#themed
两个属性都有效
<style name="AppBaseThemeDark" parent="@style/Theme.AppCompat">
<!--your other properties -->
<!--<item name="android:windowDisablePreview">true</item>-->
<item name="android:windowBackground">@null</item>
<!--your other properties -->
</style>
只需在values/styles中填写项目即可。xml:
<item name="android:windowBackground">@android:color/black</item>
例如,在AppTheme中:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
我有同样的问题,你必须更新你的风格。
style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
您的清单文件应如下所示。
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
// Other stuff
</application>
输出:
希望对您有所帮助。
答案中缺少解决此问题的推荐方法。所以我在这里添加我的答案。出现 white-screen-at-startup 问题是因为系统进程在启动应用程序时绘制的初始空白屏幕。解决此问题的常见方法是将此初始屏幕添加到您的 styles.xml
文件中以关闭此初始屏幕。
<item name="android:windowDisablePreview">true</item>
但是根据 android 文档,这会导致启动时间变长。根据 google 推荐的避免初始白屏的方法是使用 activity 的 windowBackground
主题属性并为初始 activity 提供一个简单的自定义可绘制对象。
像这样:
可绘制布局文件,my_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@android:color/white"/>
<!-- Your product logo - 144dp color version of your app icon -->
<item>
<bitmap
android:src="@drawable/product_logo_144dp"
android:gravity="center"/>
</item>
</layer-list>
在您的 styles.xml
中创建新样式
<!-- Base application theme. -->
<style name="AppTheme">
<!-- Customize your theme here. -->
</style>
<!-- Starting activity theme -->
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/my_drawable</item>
</style>
将此主题添加到清单文件 activity 中的起始
<activity ...
android:theme="@style/AppTheme.Launcher" />
当您想转换回正常主题时调用 setTheme(R.style.Apptheme)
,然后再调用 super.onCreate()
和 setContentView()
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Make sure this is before calling super.onCreate
setTheme(R.style.Theme_MyApp);
super.onCreate(savedInstanceState);
// ...
}
}
这是解决问题的推荐方法,来自 google Material Design 模式。
请将这两行复制并粘贴到您的清单应用主题中,即 res/styles/AppTheme。然后它会像魅力一样工作..
<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>
Style :-
<style name="SplashViewTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
In Manifest :-
<activity android:name=".SplashActivity"
android:theme="@style/SplashViewTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
我在主题中添加了以下两行
在 styles.xml
之下
<item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>
工作出色
请试一次。
- 创建可绘制文件splash_background.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/{your color}" />
<item>
<bitmap
android:layout_width="@dimen/size_250"
android:layout_height="@dimen/size_100"
android:gravity="center"
android:scaleType="fitXY"
android:src="{your image}"
android:tint="@color/colorPrimary" />
</item>
</layer-list>
把这个放在styles.xml
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash_background</item>
</style>
在您的 AndroidMainfest.xml 中将上述主题设置为 Launch activity。
<activity
android:name=".SplashScreenActivity"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme"
android:windowSoftInputMode="stateVisible|adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
对于调试时出现白屏的任何人,请注意,如果您正在调试,加载时间会更长。如果您构建您的发行版 APK 并将其安装在您的 phone 上,您会发现加载所需的时间要少得多。
所以debbug版本的启动时间不等于release版本的启动时间。
删除
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/splashscreen</item>
</style>
来自 style.xml 个文件
根据Google的建议Here,你不应该阻止这个白屏启动.您可以使用该主题属性来关闭启动应用时系统进程绘制的初始黑屏。
<item name="android:windowDisablePreview">true</item>
但是,不推荐这种方法,因为它可能会比不禁止预览的应用程序启动时间更长window。此外,它会迫使用户在 activity 启动时没有任何反馈地等待,让他们怀疑应用程序是否正常运行。
他们建议使用 activity 的 window 背景主题属性为开始 activity 提供简单的自定义可绘制对象,而不是禁用预览 window。
因此,这里是推荐的解决方案:
首先,创建一个新的可绘制文件,例如startup_screen.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<!-- The background color, preferably the same as normal theme -->
<item android:drawable="@android:color/white"/>
<!-- Product logo - 144dp color version of App icon -->
<item>
<bitmap
android:src="@drawable/logo"
android:gravity="center"/>
</item>
</layer-list>
其次,从您的样式文件中引用它。如果你使用夜间模式。将它添加到两个 themes.xml 文件中。
<!-- Start Up Screen -->
<style name="AppThemeLauncher" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="android:statusBarColor" tools:targetApi="l">@color/lightGray</item>
<item name="android:windowBackground">@drawable/startup_screen</item>
</style>
如果您注意到,我添加了 statusBarColor 属性以根据我的自定义设计更改状态栏的颜色。
然后,在您当前的 activity.
中添加 AppThemeLauncher 主题
<activity
android:name=".MainActivity"
android:theme="@style/AppThemeLauncher"/>
如果您想转换回正常主题,请在调用 super.onCreate() 和 setContentView() 之前调用 setTheme(R.style.AppTheme):
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Make sure this is before calling super.onCreate
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
// ...
}
}
您应该在 values-night 上有 colors.xml
(如果尚不存在,则在值文件夹旁边创建)深色主题颜色文件夹。
例如
<resources>
<color name="status_bar">#0e0e0e</color>
</resources>
(常规值文件夹中的colors.xml
将用于浅色主题)
在提供您的应用程序主题的 styles.xml
上,您将拥有背景和状态栏条目,这些条目采用必要的值。
例如
<style name="Theme.<AppName>" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/red700</item>
<item name="colorPrimaryDark">@color/red900</item>
<item name="colorAccent">@color/red700</item>
<item name="android:statusBarColor">@color/status_bar</item>
<item name="android:background">@color/status_bar</item>
</style>
AndroidManifest.xml 文件
引用了此样式
android:theme="@style/Theme.<AppName>">
众所周知,许多 Android 应用程序在第一个 Activity
成为焦点之前会非常短暂地显示白屏。在以下情况下会出现此问题:
Android 扩展全球
Application
class 和 在其中执行主要的初始化。Application
对象总是在第一个Activity
之前创建(这一事实可以 在调试器中观察到),所以这是有道理的。这就是我的案例延迟的原因。Android 在初始屏幕前显示默认预览 window 的应用程序。
设置android:windowDisablePreview = "true"
显然在这里不起作用。我也不能按照 here 所述将启动画面的父主题设置为 Theme.Holo.NoActionBar
,因为 [不幸的是] 我的启动画面使用了 ActionBar
.
同时,不扩展 Application
class 的应用不会 在以下位置显示白屏启动。
事实是,理想情况下,在 Application
对象中执行的初始化需要在 在 显示第一个 Activity
之前发生。所以我的问题是,如何使用 Application
对象在没有 的应用程序启动 时执行这些初始化?我想可能使用 Thread
或 Service
?
这是一个值得思考的有趣问题。我无法以通常的方式绕过它(通过设置 NoActionBar
主题),不幸的是,由于一些不相关的原因,我的启动画面实际上有一个 ActionBar
。
注:
我已经提到了以下问题:
White background when Android app start up
Why there is a white screen appears for 1sec when starting to run the apps in Android?
参考文献:
首先,要删除白屏,请阅读此内容 - https://www.bignerdranch.com/blog/splash-screens-the-right-way/
但更重要的是,优化您的初始负载并将任何繁重的工作推迟到您有空的时候 运行。 Post 如果你想让我们看一下你的申请 class 这里。
您是否尝试过对 onActivityCreated
进行初始化?
里面 Application
class :
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if(activity.getClass().equals(FirstActivity.class) {
// try without runOnUiThread if it will not help
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
new InitializatioTask().execute();
}
});
}
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
因为您已经知道为什么会出现这个白屏,因为后台进程或应用程序初始化或大文件,所以只需检查下面的想法以克服这个问题。
要防止应用程序启动时出现白屏,一种方法是启动画面,这只是一种非最终方法,您必须使用。
当您从 splash.xml 文件中显示启动画面时,此问题也将保持不变,
所以你必须在 style.xml 文件中为启动画面创建 ont 样式,你必须在那里设置 window 背景作为你的启动图像,然后将该主题应用到你的启动画面 activity 来自清单文件。所以现在当你 运行 应用程序时,首先它会设置主题,这样用户将能够直接看到启动图像而不是白屏。
在生命周期回调方法中,您可以声明当用户离开并重新进入 activity 时您的 activity 的行为方式。请记住 Android 的设计方式,每个应用程序都有一个生命周期。如果您对 onCreate()
方法(这是用于加载布局文件并初始化其中的任何控件的方法)施加过多负载,那么白屏将变得更加明显,因为布局文件将占用加载时间更长。
我建议在启动 activity 时使用几种不同的方法。这些是 onStart()
(应用程序加载后首先调用),onActivityCreated()
(在显示布局后调用,如果您在启动 [=23 时进行任何数据处理,则很有用) =]).
为了方便大家,下面是官方的activity生命周期图:
白色背景的问题是由于android在应用程序加载到内存时冷启动引起的,可以通过以下方式避免:
public class OnboardingWithCenterAnimationActivity extends AppCompatActivity {
public static final int STARTUP_DELAY = 300;
public static final int ANIM_ITEM_DURATION = 1000;
public static final int ITEM_DELAY = 300;
private boolean animationStarted = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onboarding_center);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus || animationStarted) {
return;
}
animate();
super.onWindowFocusChanged(hasFocus);
}
private void animate() {
ImageView logoImageView = (ImageView) findViewById(R.id.img_logo);
ViewGroup container = (ViewGroup) findViewById(R.id.container);
ViewCompat.animate(logoImageView)
.translationY(-250)
.setStartDelay(STARTUP_DELAY)
.setDuration(ANIM_ITEM_DURATION).setInterpolator(
new DecelerateInterpolator(1.2f)).start();
for (int i = 0; i < container.getChildCount(); i++) {
View v = container.getChildAt(i);
ViewPropertyAnimatorCompat viewAnimator;
if (!(v instanceof Button)) {
viewAnimator = ViewCompat.animate(v)
.translationY(50).alpha(1)
.setStartDelay((ITEM_DELAY * i) + 500)
.setDuration(1000);
} else {
viewAnimator = ViewCompat.animate(v)
.scaleY(1).scaleX(1)
.setStartDelay((ITEM_DELAY * i) + 500)
.setDuration(500);
}
viewAnimator.setInterpolator(new DecelerateInterpolator()).start();
}
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorPrimary"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="144dp"
tools:ignore="HardcodedText"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:alpha="0"
android:text="Hello world" android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
android:textColor="@android:color/white"
android:textSize="22sp"
tools:alpha="1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:alpha="0"
android:gravity="center"
android:text="This a nice text"
android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle.Inverse"
android:textSize="20sp"
tools:alpha="1"
/>
<Button
android:id="@+id/btn_choice1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:scaleX="0"
android:scaleY="0"
android:text="A nice choice"
android:theme="@style/Button"
/>
<Button
android:id="@+id/btn_choice2"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:scaleX="0"
android:scaleY="0"
android:text="Far better!"
android:theme="@style/Button"
/>
</LinearLayout>
<ImageView
android:id="@+id/img_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/img_face"
tools:visibility="gone"
/>
</FrameLayout>
img 脸
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:drawable="?colorPrimary"/>
<item>
<bitmap
android:gravity="center"
android:src="@drawable/img_face"/>
</item>
将此主题添加到清单中的启动画面
<?xml version="1.0" encoding="utf-8"?>
<resources>
<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:windowBackground">@null</item>
</style>
<style name="AppTheme.CenterAnimation">
<item name="android:windowBackground">@drawable/ll_face_logo</item>
</style>
会产生这样的效果
有关更多详细信息和更多解决方案,您可以查看此 BlogPost
您是否尝试过将启动器 activity 主题中的 android:windowBackground
属性设置为颜色或可绘制对象?
例如:
<item name="android:windowBackground">@android:color/black</item>
添加到启动器后 activity 主题将在启动时显示黑色(而不是白色)。这是隐藏长初始化的简单技巧,同时向用户展示一些东西,并且它工作正常,即使你将 Application 对象子类化。
避免使用其他构造(甚至是线程)来执行长时间的初始化任务,因为您最终可能无法控制此类构造的生命周期。 Application 对象是执行此类操作的正确位置。
请将此行添加到您的应用主题中
<item name="android:windowDisablePreview">true</item>
更多信息:https://developer.android.com/topic/performance/vitals/launch-time#themed
两个属性都有效
<style name="AppBaseThemeDark" parent="@style/Theme.AppCompat">
<!--your other properties -->
<!--<item name="android:windowDisablePreview">true</item>-->
<item name="android:windowBackground">@null</item>
<!--your other properties -->
</style>
只需在values/styles中填写项目即可。xml:
<item name="android:windowBackground">@android:color/black</item>
例如,在AppTheme中:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
我有同样的问题,你必须更新你的风格。
style.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowIsTranslucent">true</item>
</style>
您的清单文件应如下所示。
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
// Other stuff
</application>
输出:
希望对您有所帮助。
答案中缺少解决此问题的推荐方法。所以我在这里添加我的答案。出现 white-screen-at-startup 问题是因为系统进程在启动应用程序时绘制的初始空白屏幕。解决此问题的常见方法是将此初始屏幕添加到您的 styles.xml
文件中以关闭此初始屏幕。
<item name="android:windowDisablePreview">true</item>
但是根据 android 文档,这会导致启动时间变长。根据 google 推荐的避免初始白屏的方法是使用 activity 的 windowBackground
主题属性并为初始 activity 提供一个简单的自定义可绘制对象。
像这样:
可绘制布局文件,my_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@android:color/white"/>
<!-- Your product logo - 144dp color version of your app icon -->
<item>
<bitmap
android:src="@drawable/product_logo_144dp"
android:gravity="center"/>
</item>
</layer-list>
在您的 styles.xml
<!-- Base application theme. -->
<style name="AppTheme">
<!-- Customize your theme here. -->
</style>
<!-- Starting activity theme -->
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/my_drawable</item>
</style>
将此主题添加到清单文件 activity 中的起始
<activity ...
android:theme="@style/AppTheme.Launcher" />
当您想转换回正常主题时调用 setTheme(R.style.Apptheme)
,然后再调用 super.onCreate()
和 setContentView()
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Make sure this is before calling super.onCreate
setTheme(R.style.Theme_MyApp);
super.onCreate(savedInstanceState);
// ...
}
}
这是解决问题的推荐方法,来自 google Material Design 模式。
请将这两行复制并粘贴到您的清单应用主题中,即 res/styles/AppTheme。然后它会像魅力一样工作..
<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>
Style :-
<style name="SplashViewTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/splash</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
In Manifest :-
<activity android:name=".SplashActivity"
android:theme="@style/SplashViewTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
我在主题中添加了以下两行 在 styles.xml
之下 <item name="android:windowDisablePreview">true</item>
<item name="android:windowBackground">@null</item>
工作出色
请试一次。
- 创建可绘制文件splash_background.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/{your color}" />
<item>
<bitmap
android:layout_width="@dimen/size_250"
android:layout_height="@dimen/size_100"
android:gravity="center"
android:scaleType="fitXY"
android:src="{your image}"
android:tint="@color/colorPrimary" />
</item>
</layer-list>
把这个放在styles.xml
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar"> <item name="android:windowBackground">@drawable/splash_background</item> </style>
在您的 AndroidMainfest.xml 中将上述主题设置为 Launch activity。
<activity android:name=".SplashScreenActivity" android:screenOrientation="portrait" android:theme="@style/SplashTheme" android:windowSoftInputMode="stateVisible|adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
对于调试时出现白屏的任何人,请注意,如果您正在调试,加载时间会更长。如果您构建您的发行版 APK 并将其安装在您的 phone 上,您会发现加载所需的时间要少得多。
所以debbug版本的启动时间不等于release版本的启动时间。
删除
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/splashscreen</item>
</style>
来自 style.xml 个文件
根据Google的建议Here,你不应该阻止这个白屏启动.您可以使用该主题属性来关闭启动应用时系统进程绘制的初始黑屏。
<item name="android:windowDisablePreview">true</item>
但是,不推荐这种方法,因为它可能会比不禁止预览的应用程序启动时间更长window。此外,它会迫使用户在 activity 启动时没有任何反馈地等待,让他们怀疑应用程序是否正常运行。
他们建议使用 activity 的 window 背景主题属性为开始 activity 提供简单的自定义可绘制对象,而不是禁用预览 window。
因此,这里是推荐的解决方案:
首先,创建一个新的可绘制文件,例如startup_screen.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<!-- The background color, preferably the same as normal theme -->
<item android:drawable="@android:color/white"/>
<!-- Product logo - 144dp color version of App icon -->
<item>
<bitmap
android:src="@drawable/logo"
android:gravity="center"/>
</item>
</layer-list>
其次,从您的样式文件中引用它。如果你使用夜间模式。将它添加到两个 themes.xml 文件中。
<!-- Start Up Screen -->
<style name="AppThemeLauncher" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="android:statusBarColor" tools:targetApi="l">@color/lightGray</item>
<item name="android:windowBackground">@drawable/startup_screen</item>
</style>
如果您注意到,我添加了 statusBarColor 属性以根据我的自定义设计更改状态栏的颜色。
然后,在您当前的 activity.
中添加 AppThemeLauncher 主题<activity
android:name=".MainActivity"
android:theme="@style/AppThemeLauncher"/>
如果您想转换回正常主题,请在调用 super.onCreate() 和 setContentView() 之前调用 setTheme(R.style.AppTheme):
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Make sure this is before calling super.onCreate
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
// ...
}
}
您应该在 values-night 上有 colors.xml
(如果尚不存在,则在值文件夹旁边创建)深色主题颜色文件夹。
例如
<resources>
<color name="status_bar">#0e0e0e</color>
</resources>
(常规值文件夹中的colors.xml
将用于浅色主题)
在提供您的应用程序主题的 styles.xml
上,您将拥有背景和状态栏条目,这些条目采用必要的值。
例如
<style name="Theme.<AppName>" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/red700</item>
<item name="colorPrimaryDark">@color/red900</item>
<item name="colorAccent">@color/red700</item>
<item name="android:statusBarColor">@color/status_bar</item>
<item name="android:background">@color/status_bar</item>
</style>
AndroidManifest.xml 文件
引用了此样式android:theme="@style/Theme.<AppName>">