App启动时黑白屏优化

     黑白屏问题是app需要重点优化点之一,我以前都是遇到这种比较典型的问题直接上网查找相关的解决方案,筛选直接用,这样的缺点是,只知其表,不知其里,感觉自己这块懂了,但是和人实际表述的时候却说的很片面。细致梳理一下,让自己认知更深刻一下。如果有理解不对的地方,请多多指点。在此先谢过!!

1 、app的启动流程图:

android app图标周围显示黑框_初始化

小结:从图中可以看出app启动分为俩个阶段,一个是系统进程层,一个是application进程层。修改系统层需要root权限,所以真正的优化其启动速速是在application进程中。这里只分析application进程。这个流程图就是冷启动的过程。

所谓冷启动:冷启动是指进程未被创建的时候,用户launcher点击图标启动app的过程。

热启动:用户点击back键,退到手机应用图标界面,这时候进程没有被杀死,在点击应用的图标启动应用。

分析一:在此过程中,系统要为app创建一个进程,并且这个过程还包含Activity的绘制过程,这些都是比较耗时的。针对以上因素,所以Android系统框架设计了一个startWindow窗口,在app的window窗口绘制完毕之前,系统会先让startWinow窗口显示,直到activity的window窗口初始化完毕。我们所说的黑白屏就是startWindow窗口,黑或白是我们窗口的背景颜色,而背景颜色是由主题的背景颜色决定。只要我们解决这个主题背景色的问题,这个问题也就解决了。

分析二:在大中型项目中,一般都是在application中初始化组件和集成的第三方sdk,其在初始化的时候会消耗大量的时间。这就导致我们app启动比较缓慢,造成黑白屏时间过长,用户体验差的效果。

2、原因我们已经找到,下面来分析一下解决方案:

从网上各种针对此问题的文章做了总结归纳:解决方案有以下几种:

①自定义一个主题,把主题窗口背景色设置为透明,在application中设置这个主题

②修改我们的主题背景图片,图片设置为我们app的logo,在application中引用这个主题

③优化application初始化所需要的时间(一般都是开启子线程,常用的是IntentService)

3、具体实施步骤

①设置透明主题:代码如下

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

        ...
        
        <item name="android:windowIsTranslucent">true</item>
        
    </style>

此种方案特点:就是当我们点击应用图标的时候,会感觉反应不那么快,不熟悉的人以为自己没有打开成功,会连续点击。如果启动时间过长,那么用户体验比较差。

②给自定义主题设置背景图片,图片是我们的logo图片,现在市场很多app都是应用此方法。代码如下

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

        <item name="android:windowBackground">@drawable/splash</item>

        <item name="windowActionBar">false</item>

        <item name="windowNoTitle">true</item> 

    </style>

注意点:在我们的splash页面onCreate方法中要添加下面一行代码:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

这行代码的作用:不显示系统标题栏,保证我们启动的windowbackground和我们布局文件显示的大小一样大,防止图片错位。

③优化我们application onCreate方法中耗时操作,常借助IntentService

IntentService:其本质是一个特殊的service,它是一个抽象类,并且是继承Service。它可以在后台执行耗时的异步任务,当任务完成后会自动停止,优先级比较高,不容易被杀死(原因:继承service),它内部是使用HandlerThread 和handler实现异步操作的,创建IntentService时只需要实现onHandlerIntent和构造方法即可。系统执行onHandlerIntent方法时候会帮我们创建一个子线程,并且在任务执行完毕后,自动调用stopService方法,停止服务,不需要我们终止。优化代码如下:

创建IntentService,代码如下:

import android.app.IntentService;
import android.content.Intent;
import android.content.Context;


public class MyIntentService extends IntentService {


    public MyIntentService() {
        super("MyIntentService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {

        //这里进行耗时操作
    }


    public static void init(Context context) {

        Intent intent = new Intent(context, MyIntentService.class);

        context.startService(intent);

    }

}



在清单文件中进行注册:

<service
            android:name=".ui.MyIntentService"
            android:exported="false"></service>

如果想省去注册这步,可以直接借助Studio,File ->New ->Service ->IntentServic,直接创建即可。

在application中代码如下

MyIntentService.init(this);

把耗时操作直接放在,intentService中进行处理即可。

在实际应用中,这三种方案我们可以混搭使用,让其优化效果更加完美。