余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Android应用启动优化

xiyangw 2023-10-03 16:16 32 浏览 0 评论

Android应用的启动优化主要包括三部分:

第一阶段:点击桌面Launcher应用的图标,通过与AMS(ActivityManagerService)通信,启动应用的过程

第二阶段:应用Application执行过程

第三阶段:启动MainActivity执行过程

对于第一阶段,主要是桌面Launcher应用与系统AMS的交互,以及AMS启动应用的过程。这个阶段主要是系统framework在处理,我们没有办法优化。

我们可以优化的地方在第二阶段对Application的优化和第三阶段对启动MainActivity的优化。下面让我们分别来看一下。



Application优化

对于Application的优化,主要包括三部分。第一部分是attachBaseContext回调方法的优化,第二部分是onCreate回调方法的优化,第三部分就是对应用执行到MainActivity之前的白屏处理。

之所以我们会用到attachBaseContext回调方法,是因为对于Android 5.0以前的系统,是不支持多dex加载的,多dex加载功能是在5.0以后加入的。但是现在我们的应用方法数普遍都多于65525,所以一般应用都会使用多dex。对于Android 5.0以下的系统,Google给出了一个多dex方案MultiDex。这个方案需要在Application的onCreate之前进行多dex加载,所以就需要在Application的attachBaseContext回调方法中进行处理。

但是MultiDex方案需要对apk进行解压取出除主dex之外的其他dex,然后需要将这些dex分别压缩成zip格式,再进行odex优化,这些解压和压缩过程是比较耗时的。所以有一种方案就是MultiDex执行的异步化,因为MultiDex主要处理的是非主dex,主dex并不受MultiDex异步化影响。但是MultiDex异步化,就需要将Application初始化的类放到主dex中,从而不受MultiDex异步化的影响。将特定的类放到主dex中需要手动分包。Android确实给我们提供了手动分包的方法。

defaultConfig {
        minSdkVersion MIN_SDK_VERSION
        targetSdkVersion TARGET_SDK_VERSION
        multiDexEnabled true
//        multiDexKeepProguard file('multiDexKeep.pro') // keep specific classes using proguard syntax
        
    //    multiDexKeepFile file('multidex-config.txt')
    }

如上所示,就是在app目录下的build.gradle文件中加入multiDexKeepProguard或者multiDexKeepFile配置。而配置的multiDexKeep.pro或者multidex-config.txt文件就是指定哪些类需要放到主dex中。

显然,这种方法主要手动维护主dex中的类,成本比较高。除非对启动性能要求非常高,否则还是不建议这么做的。毕竟现在市场上低于5.0的手机在逐年减少。

不过,即使我们不将MultiDex异步化,而只是将Application的启动相关类放到主dex中也是可以加快应用启动速度的。我开发的应用,仅仅将Application的启动相关类放到主dex中,没有对MultiDex进行异步化,启动速度可以提高0.7s到0.8s。也就是说我们可以将启动主要的类放到主dex中,MultiDex没有异步化的话,就不会出现启动时找不到类的问题。这样就不需要每次修改Application都对multiDexKeep.pro或者multidex-config.txt文件进行修改。减少了维护成本。

接着,我们对Application的onCreate方法进行优化。

对于Application的onCreate方法,主要是初始化一些应用的sdk和网络、数据库、SP等。但是根据应用的不同,并不是所有的内容都需要在MainActivity启动之前初始化完成的。我们需要梳理业务逻辑,将MainActivity的主Fragment需要的内容在Application的onCreate方法中进行初始化,其他需要Application初始化的内容则可以放到异步线程中去处理,从而提高启动速度。

最后,让我们看一下Application由于启动耗时所出现的白屏问题。因为只有在启动MainActivity之后才会显示MainActivity的内容,所以在MainActivity启动之前,Application进行初始化的过程中,会有白屏现象。要解决这个问题,可以通过给应用设置主题的方式,将主题背景设置成启动页页面图。从而给用户一个错觉,就是点击桌面应用图标后,马上就进入了启动页。到达优化用户体验的目的。

Application的启动优化主要就以上三个方面,下面让我们来看看MainActivity可以进行哪些优化。


MainActivity是应用的主页面,展示了应用的主要内容。但是我们会发现,很多应用在进入MainActivity之前,都会先进入Splash页面和广告页面。有一种实现方案,启动页面是SplashActivity,然后用SplashActivity来判断是进入广告页面还是直接进入MainActivity页面。这也是市面上的主流实现方案。但是这种方案有一个问题。就是用户在每次通过返回键退出应用时,再通过桌面图标进入应用,并且应用没有被销毁的时候,是不会重新初始化Application的,但是启动页面确实SplashActivity,所以每次都会进入到SplashActivity再进入MainActivity。这可能不是用户想要看到的,因为SplashActivity有延时的话,用户要等待延时时间后进入MainActivity,SplashActivity没有延时的话,又会一闪而过,用户体验不好。用户真正想要看到的是应用没有重新启动的话,就最好直接能进入MainActivity。所以,我采用了以下优化方案。

将启动页面设置为MainActivity,而Splash页面和广告页面通过Fragment的形式,在MainActivity中对其进行控制。这样就可以控制只有在Application启动的时候才显示Splash页面。

另外,对Splash页面的显示时间我们也可以进行优化。一般Splash的显示时间是2s。但是就像上文所说,Application启动也会耗时的。如果给Splash页面显示时间定死2s,那用户真正看到Splash内容的时间实际为:Application启动时间+2s。而Application启动时间不同手机由于性能不同时间是不确定的。所以,我们可以统计Application初始化时间。然后让Splash页面的显示时间为:2s-Application初始化时间。如果Application初始化时间大于2s,则不展示Splash页面。

对于广告页,可以采用缓存的方式,如果数据暂时没有下载下来,可以采用之前缓存的图片展示,当然也可以不展示。

在MainActivity中,除了对Splash和广告页面的优化,对MainActivity本身的优化,还可以从以下三点进行:

1、页面渲染优化

可以通过约束布局来改造相对布局或者线性布局,从而达到减小布局层级的效果。

2、数据加载优化

为了快速加载MainActivity所需的数据,可以采用缓存的方式。如果数据异步加载成功后,会更新缓存。

另外,启动初始化时,可能会有很多接口,这里最好在启动时只通过一个接口拉取应用启动和MainActivity的主Fragment展示的所有数据。

有时MainActivity的主Fragment可能是一个Feed流,这就要分页拉取数据。

3、延时任务

对于主页面内容展示不相关的内容,可以通过IdleHandler的方式延时加载。IdleHandler是等UI主线程Looper消息队列空闲时间进行执行的。使用方式如下:

Looper.myQueue().addIdleHandler(new IdleHandler() {
    @Override
    public boolean queueIdle() {
        //你想做的任何事情
        //........
        return false;  
    }
});



以上便是Android应用启动优化的主要内容,通过对以上内容的优化,相信您的应用的启动速度一定会大大加快的。

总结:

1、对Application的优化

1)MultiDex优化

2)部分初始化任务异步化

3)设置与Splash页面展示内容相同主题

2、MainActivity的优化

1)使用MainActivity控制SplashFragment和广告Fragment的方式

2)SplashFragment展示时间动态化

3)MainActivity页面渲染优化

4)MainActivity数据加载优化

5)采用延时任务处理界面渲染无关内容

相关推荐

排序算法--归并排序_归并排序例题讲解

原理如图所示(先分割再合并):归并排序代码工作原理:1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列2、设定两个指针,最初位置分别为两个已经排序序列的起始位置3、比较两个指针所...

八大排序算法-归并排序_归并排序 算法

算法思想归并排序分为三个步骤:1.分解:将数列分解成n个子数列。(如果是将数列分成2个子数列则为2路归并)2.治理:对每个子数列进行排序操作3.合并:将两个排好序的子数列进行合并生成新的数列算法实现P...

高级排序之归并排序、希尔排序_希尔排序和归并排序区别

前言继上次排序算法简单排序算法之冒泡、插入和选择排序-Java实现版后,本文学习高级排序算法——归并排序、希尔排序,快速排序将在后续更新。本文实现代码调用方法,部分来自前一个文章:简单排序算法之冒泡、...

Excel办公应用:按合并单元格排序的三大方法

1.按姓名对科目排序重点:在"C2"中输入公式=IF(A2<>"",1,C1+1),然后下拉填充。2.按姓名添加连续序号(方法一)重点:选择"A2:A11"单元格区域,在编辑栏中输入公...

快速排序 Vs. 归并排序 Vs. 堆排序——谁才是最强的排序算法

知乎上有一个问题是这样的:堆排序是渐进最优的比较排序算法,达到了O(nlgn)这一下界,而快排有一定的可能性会产生最坏划分,时间复杂度可能为O(n^2),那为什么快排在实际使用中通常优于堆排序?昨天刚...

归并排序思路图解 #归并排序_归并排序百度百科

排序算法1.图解。OK,让它排一下。看好了,要开始排了。能看出来像递归吗?肯定算法难,但是这个次数非常的多,不用管次数。这个是帝规,就是递归。这是并,这是并,这是两个有序数,组合成一个最后的大的有序数...

排序算法学习——归并排序_归并排序算法稳定吗

我们先看归并排序的定义归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每...

动画|经典的归并排序究竟怎么玩儿?

作者|菠了个菜责编|郭芮由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列——《图解数据结构》,主要使用动画来描述常见的数据...

Excel中,多列数据统一排名,Rank函数直接搞定

Rank实现多列联合排序排序,那太简单啦,Excel中,升序降序,一个按键就可以。但,那是针对单列情况,若需要联合多列数据进行排序呢?如下图所示,需要对1、3、5列进行统一排序,咋弄嘞?联合排序案例先...

【数据结构与算法】归并排序_数据结构中归并排序

归并排序是建立在归并操作的一种高效的排序方法,该方法采用了分治的思想,比较适用于处理较大规模的数据,但比较耗内存,今天我们聊聊归并排序排序思想一天,小一尘和慧能坐在石头上,眺望着远方师傅,我听山下的柳...

C++基础算法:归并排序_经典排序算法-----归并排序(c语言实现)

归并排序(MergeSort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列。...

马士兵说之归并排序_马士兵教育的内推是真的

大家对于排序应该是挺熟悉的吧,马士兵老师特意为排序出了一波视频,当然文章是转自博客园的,马士兵老师的视频观看请点击下方的了解更多概要本章介绍排序算法中的归并排序。内容包括:1.归并排序介绍2.归并...

C++快速排序和归并排序_c++快速排序sort

快速排序每一轮挑选一个基准元素(随机选择,编程时一般选取第一个),并让比它大或小的元素移动到基准元素的两边,把数列拆解成了两个部分。而后对这两部分分别进行快速排序。时间复杂度:O(nlogn),辅助空...

经典的排序算法——归并排序_归并排序算法步骤

归并排序(MergeSort)是一种基于分治策略的高效排序算法。它将原始数组不断地分割成两个子数组,直到每个子数组只剩下一个元素为止(即基本有序),然后再通过合并已排序的子数组来最终得到完全有序的大...

归并排序_归并排序c++实现

归并排序概念:归并排序中涉及到一个概念就是分而治之,总序列化成小序列,将小序列排序好,利用排序好的小序列,再归并排序成原来要排序的序列。所以排序前先要分:functiondivide(arr){...

取消回复欢迎 发表评论: