|
|
51CTO旗下网站
|
|
vwin官网端

你必需求把握的Android冷发动优化

工作发生在发包上线的前两天,在某某云进行vwin官网测验时,提示冷发动速度低于平均值的问题,之前自己也曾尝试过优化,可是发现作用并不是很明显,作为一个有寻求的开发者,趁着有点闲暇时刻,要好好研讨一下冷发动优化问题。

作者:安卓高档架构师来历:安卓巴士Android开发者门户|2019-06-20 17:39

前语

工作发生在发包上线的前两天,在某某云进行vwin官网测验时,提示冷发动速度低于平均值的问题,之前自己也曾尝试过优化,可是发现作用并不是很明显,作为一个有寻求的开发者,趁着有点闲暇时刻,要好好研讨一下冷发动优化问题。

App的发动流程

咱们能够了解一下官方文档《App startup time》对App发动的描绘。运用发动分为冷发动、热发动、温发动。而冷发动是运用程序从零开端,里边涉及到更杂乱的常识。咱们这次首要是对运用的冷发动进行剖析和优化。运用在冷发动的时分,需求履行下面三个使命:

  • 加载和发动运用程序;
  • App发动之后当即展现出一个空白的发动窗口;
  • 创立App程序的进程;

在这三个使命履行后,体系创立了运用进程,那么运用进程会履行下一步:

  • 创立App目标;
  • 发动Main Thread;
  • 创立发动页的Activity;
  • 加载View;
  • 安置屏幕;
  • 进行初始制作;

当运用进程完结初始制作之后,体系进程用发动页的Activity来替换其时显现的布景窗口,这个时刻用户就能够运用App了。下图显现为体系和运用程序的作业流程。

你必需求把握的Android冷发动优化

从上图和上述的进程咱们能够知道,运用进程的创立,那么它肯定会履行咱们的Application的生命周期,当创立完结App的运用进程之后,主线程会初始化咱们榜首个页面MainActivity与履行MainActivity的生命周期。我特意加粗了要点,这便是咱们能够下手优化的部分。在剖析怎样优化前,咱们能够先了解一下,咱们的运用是不是需求对冷发动进行优化。

PS:其实这些都是咱们外表看到的东西,假如咱们需求完好地去深究,咱们要去详细剖析Zygote Fork进程、ActivityManagerService源码等,咱们就不在该篇中胪陈,给咱们引荐相关书本,有罗升阳的《Android体系源代码情形剖析》,刘望舒的《Android进阶解密》。

发动时刻检测

那么发动时刻多少才是适宜呢?在官方文档中描绘到当冷发动在5秒或许更长的时,Android vitals就会以为你的运用需求进行冷发动相关的优化。不过Android vitals是针对Google Play的一款运用质量检测东西,那咱们都理解,不过你能够像我相同运用阿里云的vwin官网测验,阿里云供给的数据中,冷发动的职业目标中位数是4875.67ms,咱们能够酌情比照一下。好了,下面咱们就聊一下假如检测出咱们运用的冷发动时刻。

Displayed Time

如上图一显现的Displayed Time,在Android 4.4(API等级19)及更高版别中,logcat包括一个名为Displayed的log信息,此值表明发动进程和完结在屏幕上制作相应活动之间所经过的时刻量。

你必需求把握的Android冷发动优化

ADB指令

  1. adb shell am start -W [packageName]/[packageName.MainActivity] 

在运用上一个办法Displayed Time的log打印台,咱们看到Displayed的log,后边跟着便是下面咱们需求的[packageName]/[packageName.MainActivity],咱们能够直接仿制运用,然后我 们在AS的Terminal中张贴,接着打印的便是咱们指定页面的发动时刻数据。

  1. Status: ok 
  2. Activity: com.xx.xxx/com.xx.xxxx.welcome.view.WelcomeActivity 
  3. ThisTime: 242 
  4. TotalTime: 242 
  5. WaitTime: 288 
  6. Complete 
  • ThisTime:是指调用进程中最终一个Activity发动时刻到这个Activity的 startActivityAndWait调用完毕;
  • TotalTime:是指调用进程中榜首个Activity的发动时刻到最终一个Activity的 startActivityAndWait完毕。
  • WaitTime:是startActivityAndWait这个办法的调用耗时;

reportFullyDrawn

在某些特殊场景,咱们或许不单单发动页的制作完结回调时刻就足够了,咱们需求连发动页的闪屏广告接口数据成功回调之后才算一个完好的时刻,这时咱们能够运用reportFullyDrawn

  1. public class WelcomeActivity extends MvpActivity<WelcomePresenter> implements WelcomeMvp.View { 
  2.  
  3.     @Override 
  4.     protected void onCreate(@Nullable Bundle savedInstanceState) { 
  5.         super.onCreate(savedInstanceState); 
  6.         setContentView(R.layout.activity_welcome); 
  7.         // 恳求数据 
  8.         mvpPresenter.config(); 
  9.  
  10.     } 
  11.  
  12.     @Override 
  13.     public void finishRequest() { 
  14.         // 数据回调 
  15.         reportFullyDrawn(); 
  16.     } 

你必需求把握的Android冷发动优化

PS:这个办法minSdkVersion需求API19+,所以要对SDK版别进行设置或判别。

Traceview

Traceview是Android设备的一个非常好用的功用剖析东西,它能够经过详细的界面,让咱们盯梢程序的功用,并且能明晰地检查到每一个函数的耗时和调用次数。

Systrace

Systrace非常直观地展现每个线程上面的API的调用次序和耗时状况。

Traceview和Systrace都是DDMS面板的东西,可是现在AS3.0以上的版别不再主张运用了,所以这儿就不胪陈,假如有爱好的同学,能够看我上一篇文章《Android运用优化之流通度实操》,里边有详细地阐明这两个东西的用法。

hugo

github.com/JakeWharton…

  • 咱们能够运用JakeWharton的hugo,经过注解的办法获取对应的类或许函数所耗费的时刻。咱们能够运用它对发动页Activity的生命周期来抠细节。

发动优化实操

用户体会优化

在冷发动优化的首要体会个人以为便是消除发动时的白屏/黑屏,由于白屏/黑屏关于用户运用的榜首印象便是慢、卡顿。咱们能够设置发动页的主题来到达意图。

windowDrawsSystemBarBackgrounds是对部分有体系操作栏的设置。接着是这个窗口布景色的布局。

  1. <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"
  2.   <item android:drawable="@android:color/white"/> 
  3.   <item> 
  4.     <bitmap 
  5.       android:src="@drawable/welcome_bg" 
  6.       android:gravity="center"/> 
  7.   </item> 
  8. </layer-list> 

发动页的广告展现完跳转到主页,然后咱们设置回咱们的通用款式,能够在清单文件,也能够在代码中设置。

  1. <activity 
  2.     ··· 
  3.     android:theme="@style/AppBaseFrameTheme"/> 

经过对发动页的主题设置后,就会将白屏/黑屏抹去,用户点击App的图标就展现发动图,让用户先发生发动很快的“幻觉”。一起这儿能够经过动画,让发动页与主页之间的过渡愈加天然。

Application发动优化

从上图一的剖析总结中,我对优化点Application的生命周期进行了加粗提示,接着咱们回来对这部分进行优化实操。

1. Application#attachBaseContext()

Application发动会经过attachBaseContext()-->onCreate();这时咱们从attachBaseContext的生命周期联想到什么?没错便是MultiDex分包机制。想必咱们都会发现,自从咱们办法数超出了65535处理了分包之后,发动白屏/黑屏的问题就呈现了,分包机制是导致冷发动缓慢的重要原因,而现在部分运用选用插件化的办法来防止MultiDex带来的白屏问题,这尽管是一种办法,可是开发本钱真实高,关于不少运用来说是不必要的。咱们来聊一下MultiDex优化,首要MultiDex可分红运转时和编译时两个部分:

  • 编译期:将App中的class以某种战略拆分在多个dex中,为了削减榜首个dex也就主dex中包括的class数;
  • 运转期: App发动时,虚拟机只加载主dex中的class。app发动今后,运用Multidex.install,经过反射机制修正ClassLoader中的dexElements来加载其他dex;

从网上的多篇实践剖析中,他们首要选用的是异步办法。由于App开始会先加载主dex包,那么咱们能够自主去处理分包的作业,咱们将发动页和主页需求的库、组件等首要class分在主dex中,然后到达精分主dex包的巨细,详细的操作写法,咱们能够参阅网上MultiDex发动优化文章,可是咱们要留意在主dex的分包进程中,主dex经过咱们一系列的优化操作削减了主dex的巨细,因而也增大了NoClassDefFoundError的反常的或许,此时会导致咱们的运用发动失利的危险,所以在优化后咱们必定做好测验作业。

2. Application#onCreate()

经过attachBaseContext()后就到onCreate()生命周期,想必咱们大部分的运用,会在这儿对咱们运用到的第三方库和组件进行初始化作业。由于版别不断迭代,第三方库的初始化都是直接写在onCreate()中,许多的初始化作业导致该生命周期过于沉重,咱们应该对这些第三方库进行分类。下面是我收拾我司App发动的作业分类:

你必需求把握的Android冷发动优化

看着上图,各种第三方东西初始化和事务逻辑初始化,影响发动时刻。咱们先对它们拆分红四部分。

  • 必须在onCreate()且是主进程中初始化
  • 能够推迟,可是需求在Application中初始化
  • 能够推迟到发动页的生命周期回调中初始化
  • 推迟到用的时分再初始化

咱们能够依据本身项目先列出自己项意图每一个初始化,然后进行分类。这儿尽管我没有贴详细的操作代码,不是我以为new一个线程或许创立一个IntentService太简略了就不说了,而是这儿需求留意的东西是整个冷发动优化最多的,由于自己也在这儿踩过坑。 举一个GrowingIO的比如,其时项目用的是很旧版别的GIO,其时对GIO的初始化是放在子线程操作的,遽然发包前,运营部分提出晋级GIO的SDK版别需求,升完之后编译运转觉得没什么工作就直接打包了,到线上之后运营反应新版别没了圈选数据,经过检查发现新版别的GIO是不能在子线程初始化的。从这个经验中,我以为已然同学你都对冷发动优化感爱好,所以必定不会差那几句仿制张贴的代码,这些都是要详细状况详细剖析。我来总结一下要点

  • 发动慢,不是无脑开线程,然后塞代码就完事,需求对症下药;
  • 开线程也是一门学识,Thread、ThreadPoolExecutor、AsyncTask、IntentService,终究选取哪个;
  • 假定你new好了Thread,可是有没考虑好内存走漏问题,不要一边补坑一边挖坑;
  • 留意有些第三方SDK需求在主线程初始化的;
  • 假如是运用是多进程的,留意有些第三方SDK,需求你在跟同包名进程下进行初始化;
  • 其实有许多项目,经过多年的版别迭代都是没有收拾过代码的,那些旧代码、无用代码都是需求归类收拾的;

发动页Activity的优化

布局优化 咱们的发动页Activity包括有发动图控件、闪屏广告图控件、闪屏广告视频控件、初次装置介绍图控件。关于布局优化而言,除了发动图控件外,其他都不是App发动时都要初始化的控件,这时咱们能够运用ViewStub。针对指定的事务场景,初始化指定的控件。

防止I/O操作 咱们知道I/O操作不是实时的,例如数据库的读写、SharedPreferences#apply()。咱们要留意这些操作有没堵塞主线程地履行,一起咱们能够运用StrictMode严厉形式,运用它能够检测咱们在发动的时分有没正确进行磁盘读写操作。

留意图片bitmap的加载速度和编码格局 咱们能够知道,发动页大部分的状况下都是图片的显现,那么咱们在图片这方面怎样抠细节呢,那便是对各种第三方图片加载库的选用了Glide、Picasso、Fresco等,还有是PREFER_ARGB_8888、PREFER_RGB_565的选取问题,咱们能够针对归于自己项目状况进行选取。

对矢量图VectorDrawable目标的运用 矢量图的中心是省时刻、省空间。而关于某些用户,它的发动图或许不是一张图片,它非常精约,就一个logo,这个时分咱们能够考虑一下矢量图的用法。

留意Activity中的发动生命周期的回调 咱们在Application#onCreate()优化,将某些不是很必要的网络恳求,搬到了欢迎页中,可是咱们也不能直接将这个网络恳求操作直接拷贝到发动页的onCreate()中,咱们能够奇妙地运用Activity生命周期中的Activity#onWindowFocusChanged(boolean hasFocus) ,这个是一切控件初始化完的真实回调,咱们能够将网络操作放在这儿,当然咱们还能够运用Service。

冷发动优化总结

关于冷发动优化,需求咱们一步步去剖析,不像布局优化那般照搬套路,所以在官方文档中也屡次呈现bottleneck瓶颈这个词汇,阐明晰咱们的冷发动优化之路不会一望无际,咱们要善用Android Studio‘s CPU profiler(有时机咱们详细剖析一下该功用的运用),由于网上许多的总结是经过Traceview和Systrace,可是这两者在AS3.0版别的晋级现已放弃,旁边面反映到咱们要勤看官方文档,用自己的榜首视点去考虑Android的改变,而不是经过他人的翻译剖析。最终咱们相互勉励一下,在现在的Android市场竞争益发剧烈,怎样在竞品比照中胜出,还需求咱们一步步地把一个个的细节做好做完美。

【责任修改:未丽燕 TEL:(010)68476606】

点赞 0
共享:
咱们都在看
猜你喜爱

订阅专栏+更多

20个局域网建造改造事例

20个局域网建造改造事例

网络建立技巧
共20章 | 捷哥CCIE

376人订阅学习

WOT2019全球人工智能技能峰会

WOT2019全球人工智能技能峰会

通用技能、运用领域、企业赋能三大章节,13大技能专场,60+国内外一线人工智能精英大咖站台,共享人工智能的渠道东西、算法模型、语音视觉等技能主题,助力人工智能落地。
共50章 | WOT峰会

0人订阅学习

Spring Boot 爬虫查找轻松游

Spring Boot 爬虫查找轻松游

全栈式开发之旅
共4章 | 美码师

87人订阅学习

读 书 +更多

通晓Spring 2.0

本书是关于Spring 2.0的威望教程,是Java/Java EE开发者必备的参阅书。本书翔实体系地介绍了Java EE的根底常识、Spring 2.0的各种功用,以...

订阅51CTO邮刊

点击这儿检查样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客