Android 应用启动时出现黑白屏问题分析及解决办法

目录

前言

一、案件重演

二、原因分析

三、解决方案


前言

在日常Android项目开发工作中,我们经常会遇到一种小情况,就是点击应用桌面图标后会出现片刻的黑屏效果。虽然这种情况并不是一个bug,也不是人为造成的结果,但这样总归会觉得是我们的应用启动缓慢和运行卡顿。当用户觉得这款应用不流畅,即降低用户体验,造成用户流失就是公司的损失了。因此,本章就来搞清楚这种情况是怎么回事,如何解决这一问题。

 

一、案件重演

一般应用开发中都会创建启动页、欢迎页或广告页,SplashActivity.class 实现代码大致如下:

AndroidManifest.xml

<activity
      android:name=".SplashActivity"
      android:screenOrientation="portrait"

      android:theme="@style/ThemeSplash">  //自定义主题

      <intent-filter>
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
</activity>

styles.xml    (注意细节!)

    <style name="ThemeSplash" parent="Theme.AppCompat.Light.NoActionBar">

        //注意!!window背景设为白色!!!
        <item name="android:windowBackground">@android:color/white</item>

        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="windowActionBar">false</item>
         //没有状态栏,即全屏
        <item name="windowNoTitle">true</item> 
    </style>

activity_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="@mipmap/bg_splash"
    tools:context="com.example.makeapp.SplashActivity">
</RelativeLayout>

SplashActivity.class

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
       
    }
}

这样运行起来,会出现白屏现象。

 

二、原因分析

如果不懂视图加载原理的同学,建议移步学习Android setContentView()\LayoutInflater\View 源码原理分析 

从上面在SplashActivity.class中可见:onCreate生命周期中执行了setContentView(R.layout.activity_splash)。我们进入setContentView源码中看一下。

public void setContentView(@LayoutRes int layoutResID) {
   getWindow().setContentView(layoutResID);
   initWindowDecorActionBar();
}

这里注意调用的是  getWindow().setContentView(layoutResID)  。这说明先调用了Window的setContentView方法。(Window是一个抽象对象,它的具体实现类就是PhoneWindow)

我们再看一下PhoneWindow中的setContentView() 的源码:

@Override
public void setContentView(int layoutResID) {
 
   if (mContentParent == null) {
       installDecor();
   } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
       mContentParent.removeAllViews();
   }
 
   if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
       final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
               getContext());
       transitionTo(newScene);
   } else {

     //解析布局
       mLayoutInflater.inflate(layoutResID, mContentParent);

   }
   mContentParent.requestApplyInsets();
   final Callback cb = getCallback();
   if (cb != null && !isDestroyed()) {
       cb.onContentChanged();
   }
}

注意其中调用了  mLayoutInflater.inflate(layoutResID, mContentParent);  说明是将SplashActivity的R.layout.activity_splash布局加载到了其宿主PhoneWindow中了。

所以,在页面启动时,系统会先绘制窗体布局,这时候SplashActivity布局资源还没加载完成,于是就先显示了window的默认背景色。

 

三、解决方案

1、我们将把启动图 bg_splash.png 设置为窗体背景色;

2、在窗体背景色显示时,后台请求广告图或加载应用中的广告资源;

3、广告图请求成功或失败就显示SplashActivity自己真实的样子。

     <style name="ThemeSplash" parent="Theme.AppCompat.Light.NoActionBar">
          //设置启动图为窗体背景色
        <item name="android:background">@mipmap/bg_splash</item>

        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

至此,应该可以就不会出现黑白屏了。


参考链接https://blog.csdn.net/zivensonice/article/details/51691136

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值