App 冷启动缓慢出现白屏之终极解决方案 — IntentService 高效异步处理

什么叫作冷启动

第一次启动或者被用户主动杀死app进程,或者被系统主动回收掉,整个app的后台任务被清理,回到桌面再次点击app的桌面图标启动app。java

特色android

后台任务所有结束,再次启动数据库

固然还有与之对应的热启动性能优化

热启动bash

用户点击返回键退推到桌面上,后台任务没有被杀死。再次点击桌面图标启动app微信

特色多线程

未清理后台任务,再次启动app

app启动时,每个app都会至少建立一个进程出来,一些启动多线程任务的会建立出来多个进程。异步

为何会出现白屏现象

首先咱们要知道当打开一个Activity的时候发生了什么?ide

  • 在一个Activity打开时,若是该Activity所属的Application尚未启动,那么系统会为这个Activity建立一个进程
  • 每建立一个进程都会调用一次Application,因此Application的onCreate()方法可能会被调用屡次

  • 在进程的建立和初始化中,势必会消耗一些时间,在这个时间里,WindowManager会先加载APP里的主题样式里的窗口背景(windowBackground)做为预览元素,而后才去真正的加载布局

  • 若是这个时间过长,而默认的背景又是黑色或者白色,这样会给用户形成一种错觉,这个APP很卡,很不流畅,天然也影响了用户体验。

效果图对比较:

启动过长出现白屏效果:

启动过长出现白屏效果
启动过长出现白屏效果

利用IntentService优化后的效果:

利用IntentService优化后的效果
利用IntentService优化后的效果

在application里作一些耗时的一些逻辑:

耗时操做
耗时操做

利用IntentService进行帮助application逻辑相关的异步处理

application相关处理
application相关处理

MyIntentService:

MyIntentService
MyIntentService

该项目是一个关于GreenDao的一个学习案例

GreenDao的一个学习案例
GreenDao的一个学习案例
:

相关该用例中的demo相关CSDN链接:

download.csdn.net/detail/andr…

另外参考了网上的另外2种方式这里也进行总结一下.

  • 一、将背景图设置成咱们APP的Logo图,做为APP启动的引导,如今市面上大部分的APP也是这么作的。
<style name="AppWelcome" parent="AppTheme">
        <item name="android:windowBackground">@mipmap/bg_welcome_start</item>
 </style>复制代码
  • 二、将背景颜色设置为透明色,这样当用户点击桌面APP图片的时候,并不会"当即"进入APP,并且在桌面上停留一会,其实这时候APP已是启动的了,只是咱们心机的把Theme里的windowBackground的颜色设置成透明的,强行把锅甩给了手机应用厂商(手机反应太慢了啦,哈哈),其实如今微信也是这样作的
<style name="Appwelcome" parent="android:Theme.Translucent.NoTitleBar.Fullscreen"/>复制代码

透明化这种作法须要注意的一点,若是直接把Theme引入Activity,在运行的时候可能会出现以下异常:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

这个是由于使用了不兼容的Theme,例如我这里的Activity继承了AppCompatActivity,解决方案很简单:

  • 一、让其Activity集成Activity而不要集成兼容性的AppCompatActivity
  • 二、在onCreate()方法里的super.onCreate(savedInstanceState)以前设置咱们原来APP的Theme
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
            setTheme(R.style.AppTheme);
            super.onCreate(savedInstanceState);
    }
}复制代码

最后别忘了两种方式都要在 咱们都须要将Theme引入对应的Activity

<activity
            android:name=".app.main.MainActivity"
            android:theme="@style/AppWelcome"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>复制代码

IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,而后接受处理完成后,会清理线程,而且关掉服务。

IntentService有如下特色:

  • 它建立了一个独立的工做线程来处理全部的经过onStartCommand()传递给服务的intents。

  • 建立了一个工做队列,来逐个发送intent给onHandleIntent()。

  • 不须要主动调用stopSelft()来结束服务。由于,在全部的intent被处理完后,系统会自动关闭服务。

  • 默认实现的onBind()返回null

  • 默认实现的onStartCommand()的目的是将intent插入到工做队列中

此次主要是针对于APP第一次启动过长 出现白屏的解决方案.

如何避免app启动时间过长呢?

  • 一、不要让Application参与业务的操做

  • 二、不要在APPlication进行耗时操做,好比有些开发者会在本身的APP里一系列文件夹或文件(好比我本身),这些I/O操做应该放到"确实该使用的时候再去建立"亦或者是数据库的一些操做。

  • 三、不要以静态变量的方式在Application中保存数据等。

另外性能分析工具请参考:

BlockCannery-一个强大的Android程序调试工具,轻松帮你找出卡顿

性能优化篇:

Android性能优化 (1)—— 内存溢出和内存泄漏的介绍

相信本身,没有作不到的,只有想不到的

若是你以为此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

技术+职场
技术+职场
相关文章
相关标签/搜索