天天看点

冷启动与热启动,AsyncTask,HandlerThread,IntentService,Service 保活,IntentService

目录

​​说下冷启动与热启动是什么,区别,如何优化,使用场景等。​​

​​Android 中的线程有那些,原理与各自特点:AsyncTask,HandlerThread,IntentService​​

​​Service 保活​​

​​ IntentService原理分析​​

说下冷启动与热启动是什么,区别,如何优化,使用场景等。

app冷启动: 当应用启动时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用, 这个启动方式就叫做冷启动(后台不存在该应用进程)。冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

app热启动: 当应用已经被打开, 但是被按下返回键、Home键等按键时回到桌面或者是其他程序的时候,再重新打开该app时, 这个方式叫做热启动(后台已经存在该应用进程)。热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application

冷启动的流程

当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上

冷启动的生命周期简要流程::

Application构造方法 –> attachBaseContext()–>onCreate –>Activity构造方法 –> onCreate() –> 配置主体中的背景等操作 –>onStart() –> onResume() –> 测量、布局、绘制显示

冷启动的优化主要是视觉上的优化,解决白屏问题,提高用户体验,所以通过上面冷启动的过程。能做的优化如下:

减少 onCreate()方法的工作量

不要让 Application 参与业务的操作

不要在 Application 进行耗时操作

不要以静态变量的方式在 Application 保存数据

减少布局的复杂度和层级

减少主线程耗时

为什么冷启动会有白屏黑屏问题?原因在于加载主题样式Theme中的windowBackground等属性设置给MainActivity发生在inflate布局当onCreate/onStart/onResume方法之前,而windowBackground背景被设置成了白色或者黑色,所以我们进入app的第一个界面的时候会造成先白屏或黑屏一下再进入界面。解决思路如下

1.给他设置 windowBackground 背景跟启动页的背景相同,如果你的启动页是张图片那么可以直接给 windowBackground 这个属性设置该图片那么就不会有一闪的效果了

<span style="color:#000000"><code><style name=``"Splash_Theme"` `parent=``"@android:style/Theme.NoTitleBar"``>`
    <item name=``"android:windowBackground"``>@drawable/splash_bg</item>`
    <item name=``"android:windowNoTitle"``>``true``</item>`
</style>`
</code></span>      

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

2.采用世面的处理方法,设置背景是透明的,给人一种延迟启动的感觉。,将背景颜色设置为透明色,这样当用户点击桌面APP图片的时候,并不会"立即"进入APP,而且在桌面上停留一会,其实这时候APP已经是启动的了,只是我们心机的把Theme里的windowBackground 的颜色设置成透明的,强行把锅甩给了手机应用厂商(手机反应太慢了啦)

<span style="color:#000000"><code><style name=``"Splash_Theme"` `parent=``"@android:style/Theme.NoTitleBar"``>`
    <item name=``"android:windowIsTranslucent"``>``true``</item>`
    <item name=``"android:windowNoTitle"``>``true``</item>`
</style>`
</code></span>      

3.以上两种方法是在视觉上显得更快,但其实只是一种表象,让应用启动的更快,有一种思路,将 Application 中的不必要的初始化动作实现懒加载,比如,在SpashActivity 显示后再发送消息到 Application,去初始化,这样可以将初始化的动作放在后边,缩短应用启动到用户看到界面的时间

Android 中的线程有那些,原理与各自特点:AsyncTask,HandlerThread,IntentService

AsyncTask原理:内部是Handler和两个线程池实现的,Handler用于将线程切换到主线程,两个线程池一个用于任务的排队,一个用于执行任务,当AsyncTask执行execute方法时会封装出一个FutureTask对象,将这个对象加入队列中,如果此时没有正在执行的任务,就执行它,执行完成之后继续执行队列中下一个任务,执行完成通过Handler将事件发送到主线程。AsyncTask必须在主线程初始化,因为内部的Handler是一个静态对象,在AsyncTask类加载的时候他就已经被初始化了。在Android3.0开始,execute方法串行执行任务的,一个一个来,3.0之前是并行执行的。如果要在3.0上执行并行任务,可以调用executeOnExecutor方法

HandlerThread原理:继承自 Thread,start开启线程后,会在其run方法中会通过Looper 创建消息队列并开启消息循环,这个消息队列运行在子线程中,所以可以将HandlerThread 中的 Looper 实例传递给一个 Handler,从而保证这个 Handler 的 handleMessage 方法运行在子线程中

IntentService原理:继承自Service,它的内部封装了 HandlerThread 和Handler,可以执行耗时任务,同时因为它是一个服务,优先级比普通线程高很多,所以更适合执行一些高优先级的后台任务,HandlerThread底层通过Looper消息队列实现的,所以它是顺序的执行每一个任务。可以通过Intent的方式开启IntentService,IntentService通过handler将每一个intent加入HandlerThread子线程中的消息队列,通过looper按顺序一个个的取出并执行,执行完成后自动结束自己,不需要开发者手动关闭

IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题:Service不会专门启动一条单独的进程,Service与他所在应用位于同一个进程中。

Service也不是专门一条新进程,因此不应该在Service中直接处理耗时的任务。

特点:

IntentService会创建独立的worker线程来处理所有的Intent请求;

会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程的问题;

所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service;

为Service的onBind()提供默认实现,返回null;

为Service的onStartCommand提供默认实现,将请求Intent添加到队列中;

Service 保活

1.在 onStartCommand 中返回 START_STICKY(粘性的)

这种方式并不能保证 Service 不被杀死,只是提高 Service 被杀死后快速重启概率。

2.双进程守护

为后台常驻 Service 设置守护进程,相互监听对方的状态,当监测到对方被杀死后立即重启对方 Service 达到守护 service 的目的。

 IntentService原理分析