Android 性能调优口试题

源代码 2024-9-16 20:12:19 42 0 来自 中国
1.1 谈谈你对Android性能优化方面的相识?


  • 启动优化: application中不要做大量耗时操纵,如果必须的话,发起异步做耗时操纵
  • 结构优化:利用合理的控件选择,少嵌套。(合理利用 include,merge,viewStub等利用)
  • apk优化(资源文件优化,代码优化,lint检查,.9.png,合理利用shape更换图片,webp等)
  • 性能优化,网络优化,电量优化
    制止轮询,只管利用推送
    应用处于配景时,禁用某些数据传输
    限定访问频率,失败后不要无穷重连
    选用符合的定位服务(GPS定位,网络定位,被动定位)
    利用缓存
    startActivityForResult更换发送广播
  • 内存优化
    循环只管不利用局部变量
    制止在onDraw中创建对象,onDraw会被频仍调用,轻易造成内存抖动。循环中创建大的对象,也是云云。
    不消的对象实时开释
    数据库的cursor实时关闭
    adapter利用缓存
    注册广播后,在生命周期竣事时反注册
    实时关闭流操纵
    图片只管利用软引用,较大的图片可以通过BitmapFactory缩放后再利用,并实时recycler。别的加载巨图时不要利用setImageBitmap或setImageResourse或BitmapFactory.decodeResource,这些方法拿到的都是bitmap的对象,占用内存较大。可以用BitmapFactory.decodeStream方法共同BitmapFactory.Options举行缩放制止static成员变量引用资源淹灭过多实例制止静态内部类的引用
1.2 一样平常什么情况下会导致内存走漏标题?


  • 资源对象没关闭造成的内存走漏(如: Cursor、File等)
  • ListView 的 Adapter 中没有利用缓存的ConvertView
  • Bitmap 对象不在利用时调用recycle()开释内存
  • 聚集中对象没清算造成的内存走漏(特殊是 static 修饰的聚集)
  • 接收器、监听器注册没取消造成的内存走漏
  • Activity 的 Context 造成的走漏,可以利用ApplicationContext
  • Handler 造成的内存走漏标题(一样平常由于 Handler 生命周期比其外部类的生命周期长引起的)
1.3 自定义 Handler 时怎样有效地制止内存走漏标题?


  • 自定义的静态Handler
  • 可以加一个弱引用
  • 尚有一个主意的就是当你Activity被烧毁的时候如果尚有消息没有发出去就remove掉吧
  • removeCallbackSandMessages去扫除Message和 Runnable 加 null 写在生命周的onDestroy()就行
1.4 哪些情况下会导致oom标题?


  • 比方 Handler 在界面烧毁的时候消息还未发送
  • File没有关流
  • 查询到效果还没有制止
  • 内部类持有外部类引用得不到开释
  • 不消的对象最好 null 让 GC 接纳一下
  • 图片资源什么的最好加一个软引用
1.5 ANR 出现的场景以及办理方案?

在Android中,应用的相应性被活动管理器(ActivityManager)和窗口管理器(Window Manager)这两个体系服务所监督。当用户触发了输入事故(如键盘输入,点击按钮等),如果应用5秒内没有相应用户的输入事故,那么,Android会以为该应用无相应,便弹出ANR对话框。而弹出ANR非常,也告急是为了提拔用户体验。
办理方案是对于耗时的操纵,好比访问网络、访问数据库等操纵,必要开辟子线程,在子线程处理处罚耗时的操纵,主线程告急实现UI的操纵。
1.6 谈谈Android中内存优化的方式?

关于内存走漏,一样平常像单例模式的利用不当、聚集的操纵不当、资源的缺乏有效的接纳机制、Handler、线程的利用不当等等都有大概引发内存走漏。

  • 单例模式引发的内存走漏
    缘故原由:单例模式里的静态实例持有对象的引用,导致对象无法被接纳,常见为持有Activity的引用
    优化:改为持有Application的引用,大概不持有利用的时候传递。
  • 聚集操纵不当引发的内存走漏
    缘故原由:聚集只增不减
    优化:有对应的删除或卸载操纵
  • 线程的操纵不当引发的内存走漏
    缘故原由:线程持有对象的引用在配景执行,与对象的生命周期不划一
    优化:静态实例+弱引用(WeakReference)方式,使其生命周期划一
  • 匿名内部类/非静态内部类操纵不当引发的内存走漏
    缘故原由:内部类持有对象引用,导致无法开释,好比各种回调
    优化:保持生命周期划一,改为静态实例+对象的弱引用方式(WeakReference)
  • 常用的资源未关闭接纳引发的内存走漏
    缘故原由:BroadcastReceiver,File,Cursor,IO流,Bitmap等资源利用未关闭
    优化:利用后有对应的关闭和卸载机制
  • Handler利用不当造成的内存走漏
    缘故原由:Handler持有Activity的引用,其发送的Message中持有Handler的引用,当队列处理处罚Message的时间过长会导致Handler无法被接纳
    优化:静态实例+弱引用(WeakReference)方式
内存溢出

缘故原由:

  • 内存走漏长时间的积聚
  • 业务操纵利用超大内存
    优化:
  • 调解图像巨细后再放入内存、实时接纳
  • 不要过多的创建静态变量
1.7 谈谈结构优化的本事?

1、低沉Overdraw(过分绘制),淘汰不须要的配景绘制
2、淘汰嵌套条理及控件个数
3、利用Canvas的clipRect和clipPath方法限定View的绘制地域
4、通过imageDrawable方法举行设置制止ImageView的background和imageDrawable重叠
5、借助ViewStub按需耽误加载
6、选择符合的结构范例
7、熟悉API只管借助体系现有的属性来实现一些UI效果
1.8 Android中的图片优化方案?


  • 起首我们可以对图片举行二次采样,从本质上淘汰图片的内存占用。就是将大图片缩小之后放入到内存中,以实现减小内存的目标
  • 其次就是接纳三层缓存架构,进步图片的访问速率。三层缓存架构是内存-文件-网络。内存是访问速率最快的部门但是分配的空间有限,以是不大概占用太多。此中内存缓存可以接纳LRU算法(近来最少利用算法),来确定要删除内存中的那些图片,生存那些图片。文件就是将图片生存到本地,可以使SD卡中,也可以是手机内部存储中。网络就是访问网络下载图片,举行图片的加载。
  • 常见的png,JPG,webp等格式的图片在设置到UI上之前必要颠末解码过程,而图片接纳差别的码率,也会造成对内存的占用差别。
  • 末了一点,也是图片优化最告急的一点。重用Bitmap.
  • 不利用Bitmap要记得实时接纳,减小内存的开销
1.9 Android Native Crash标题怎样分析定位?


  • 利用breakpad,dump Native瓦解时日记信息
  • 利用addr2line跟ndk-strace等工具,根据瓦解日记偏移量定位具体源码位置
  • 根据信号提示举行具体处理处罚
    此步调的难点在于:
    Native Crash的时候整个app的状态是极其不稳固的,很大概由于生存日记(大概上报日记)等操纵引起其他非常,以是此时最好fork一个子历程来生存当前历程的日记。
1.10 谈谈怎么给apk瘦身?

第1条:利用一套资源

这是最根本的一条规则,但非常告急。
对于绝大对数APP来说,只必要取一套操持图就充足了。
鉴于现在分辨率的趋势,发起取720p的资源,放到xhdpi目次。
相对于多套资源,只利用720P的一套资源,在视觉上差异不大,许多大公司的产物也是云云,但却能明显的淘汰资源占用巨细,趁便也能减轻操持师的出图工作量了。
注意,这里不是说把不是xhdpi的目次都删除,而是夸大生存一套操持资源就够了。
第2条:开启minifyEnabled肴杂代码

在gradle利用minifyEnabled举行Proguard肴杂的设置,可大大减小APP巨细:
    android {        buildTypes {            release {                minifyEnabled true            }        }    }在proguard中,是否生存符号表对APP的巨细是有明显的影响的,可酌情不生存,但是发起只管生存用于调试。
具体proguard的相干的设置和原理可自行查阅。
第3条:开启shrinkResources去除无用资源

在gradle利用shrinkResources去除无用资源,效果非常好。
    android {        buildTypes {            release {                shrinkResources true            }        }    }第4条:删除无用的语言资源
大部门应用着实并不必要支持几十种语言的国际化支持。
还好强盛的gradle支持语言的设置,好比国内应用只支持中文:
    android {        defaultConfig {            resConfigs "zh"        }    }第5条:利用Tinypng有损压缩

android打包自己会对png举行无损压缩,以是利用像Tinypng如许的有损压缩是有须要的。
重点是Tinypng利用智能有损压缩技能,以只管少的失真换来图片巨细的锐减,效果非常好,猛烈推荐。
Tinypng的官方网站:TinyPNG – Compress WebP, PNG and JPEG images intelligently
第6条:利用jpg格式

如果对于非透明的大图,jpg将会比png的巨细有明显的上风,固然不是绝对的,但是通常会减小到一半都不止。
在启动页,活动页等之类的大图展示区接纳jpg将黑白常明智的选择。
第7条:利用webp格式

webp支持透明度,压缩比比jpg更高但表现效果却不输于jpg,官方评测quality参数即是75平衡最佳。
相对于jpg、png,webp作为一种新的图片格式,限于android的支持情况临时还没用在手机端广泛应用起来。从Android 4.0+开始原生支持,但是不支持包罗透明度,直到Android 4.2.1+才支持表现含透明度的webp,利用的时候要特殊注意。
官方先容
第8条:缩小大图

如果颠末上述步调之后,你的工程内里尚有一些大图,思量是否有须要维持如许的大尺寸,是否能适当的缩小。
究竟上,由于操持师出图的缘故原由,我们拿到的许多图片完全可以适当的缩小而对视觉影响是极小的。
第9条:覆盖第三库里的大图

有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以思量用1x1的透明图片覆盖。
你大概会有点不舒服,由于你的drawable下竟然包罗了一些莫名其妙的名称的1x1图片…
第10条:删除armable-v7包下的so

根本上armable的so也是兼容armable-v7的,armablev7a的库会对图形渲染方面有很大的改进,如果没有这方面的要求,可以精简。
这里不清除有少少数装备会Crash,大概和差别的so有一定的关系,请各人务必测试全面后再发布。
第11条:删除x86包下的so

与第十条差别的是,x86包下的so在x86型号的手机是必要的,如果产物没用这方面的要求也可以精简。
发起实际工作的设置是只生存armable、x86下的so文件,算是一个折中的方案。
第12条:利用微信资源压缩打包工具

微信资源压缩打包工具通过短资源名称,接纳7zip对APP举行极致压缩实现减小APP的目标,效果非常的好,猛烈推荐。
详情参考:Android资源肴杂工具利用说明
原理先容:安装包立减1M–微信Android资源肴杂打包工具发起开启7zip,注意白名单的设置,否则会导致有些资源找不到,官方已经发布AndResGuard到gradle中了,非常方便:
    apply plugin:'AndResGuard'    buildscript {        dependencies {            classpath 'com.tencent.mm:AndResGuard-gradleplugin:1.1.7'        }    }    andResGuard {        mappingFile = null        use7zip = true        useSign = true        keepRoot = false        // add < your_application_id >.R.drawable.icon into whitelist.        // because the launcher will get thgge icon with his name        def packageName = <your_application_id > whiteList = [        //for your icon                 packageName + ".R.drawable.icon",                //for fabric                 packageName + ".R.string.com.crashlytics.*",                //for umeng update                packageName + ".R.string.umeng*",                packageName + ".R.string.UM*",                packageName + ".R.string.tb_*",                packageName + ".R.layout.umeng*",                packageName + ".R.layout.tb_*",                packageName + ".R.drawable.umeng*",                packageName + ".R.drawable.tb_*",                packageName + ".R.anim.umeng*",                packageName + ".R.color.umeng*",                packageName + ".R.color.tb_*",                packageName + ".R.style.*UM*",                packageName + ".R.style.umeng*",                packageName + ".R.id.umeng*"        ]        compressFilePattern = [                "*.png",                "*.jpg",                "*.jpeg",                "*.gif",                "resources.arsc"        ]        sevenzip {            artifact = 'com.tencent.mm:SevenZip:1.1.7'            //path = "/usr/local/bin/7za"        }    }会天生一个andresguard/resguard的Task,主动读取release署名举行重新肴杂打包。
第13条:利用provided编译

对于一些库是按照必要动态的加载,大概在某些版本并不必要,但是代码又不方便去除否则会编译不外。
利用provided可以包管代码编译通过,但是实际打包中并不引用此第三方库,实现了控制APP巨细的目标。
但是也同时就必要开辟者自己判定不引用这个第三方库时就不要执行到相干的代码,制止APP瓦解。
第14条:利用shape配景

特殊是在扁平化盛行的当下,许多纯色的渐变的圆角的图片都可以用shape实现,代码灵活可控,省去了量的配景图片。
第15条:利用着色方案

信任你的工程里也有许多selector文件,也有许多相似的图片只是颜色差别,通过着色方案我们能大大减轻如许的工作量,淘汰如许的文件。
借助于android support库可实现一个全版本兼容的着色方案,参考代码:DrawableLess.java
第16条:在线化素材库

如果你的APP支持素材库(好比谈天心情库)的话,思量在线加载模式,由于每每素材库都有不小的体积。
这一步必要开辟者实现在线加载,一方面增长代码的复杂度,一方面进步了APP的流量斲丧,发起酌情选择。
第17条:制止重复库

制止重复库看上去是天经地义的,但是秘密总是藏的很深,一定要当心你引用的第三方库又引用了哪个第三方库,这就很轻易出现功能重复的库了,好比利用了两个图片加载库:Glide和Picasso。
通过检察exploded-aar目次和External Libraries大概反编译天生的APK,只管制止重复库的巨细,减小APP巨细。
第18条:利用更小的库

同样功能的库在巨细上是差别的,乃至会悬殊很大。
如果并无对某个库特殊需求而又对APP巨细有严酷要求的话,比力这些雷同功能第三方库的巨细,选择更小的库会减小APP巨细。
第19条:支持插件化

已往的一年,插件化技能雨后春笋一样的都冒了出来,这些技能支持动态的加载代码和动态的加载资源,把APP的一部门分离出来了,对于业务巨大的项目来说非常有效,极大的分解了APP巨细。
由于插件化技能必要一定的技能保障和服务端体系支持,有一定的风险,如无须要(好比一些小型项目,也没什么扩展业务)就不必要了,发起酌情选择。
第20条:精简功能业务

这条完全取决于业务需求。
从统计数据分析砍掉一些没用的功能是完全有大概的,乃至干脆去掉一些花哨的功能出个轻聊版、极速版也不是不可以的。
第21条:重复执行第1到20条

多次执行上述步调,你总能发现一些蛛丝马迹,这是一个好消息,不是吗?
第22条:Facebook的redex优化字节码
redex是facebook发布的一款android字节码的优化工具,必要按照说明文档自行设置一下。
redex input.apk -o output.apk --sign -s <KEYSTORE> -a <KEYALIAS> -p <KEYPASS>1.11 谈谈你是怎样优化App启动过程的?


  • 把Application onCreate中要执行的方法分为同步和异步,只管去耽误执行大概利用空闲线程去初始化一些方法
  • 设置一个启动配景,制止白屏大概黑屏,然后做一个空的Activity这个Activity只做一件事,就是跳转到真的Activity,由于启动速率和Application onCreate的耗时和第一个Activity的绘制有关,
上面都是easy的做法

  • 利用redex工具优化dex , 由于class字节码分布在差别的dex中,以是启动的时候必须逐个查找一些文件,他们散列分布在差别的dex中,查找起来耗时又不方便,利用redex把相干的class放在同一个dex包下,制止同一个dex包被多次查找
  • 在attachBaseContext中新起一个历程去加载mutildex可以加快App启动页的打开(大概在启动页中会期待,但是加快了从launcher到启动页的速率)
1.12 谈谈代码肴杂的步调?

开启肴杂

  • 检察项目利用的第三方哪些必要设置肴杂
  • 保持反射native对应的类和方法不肴杂
  • 保持自定义类不肴杂
  • 保持实体类参与序列化的不肴杂
  • 体系组件等一些固定方法会被体系调用的不肴杂
1.13 谈谈App的电量优化?

优化方案总结
(1)GPS

利用要审慎,如准确度不高可用WiFi定位大概基站定位,可用
非要用的话,注意定位数据的复用和定位频率的阈值
(2)Process和Service

按需启动,用完就退出
(3)网络数据交互

淘汰网络网络哀求次数和数据量
WiFi比手机网络省电
(4)CPU

淘汰I/O操纵(包罗数据库操纵)
淘汰大量的盘算
(5)淘汰手机硬件交互

利用频率优化和选择低功耗模式
1.14 谈谈怎样对WebView举行优化?


  • 单/多历程化:WebView在独立的历程内里,那么WebView的历程瓦解不会影响到主历程运行;同时WebView的安全毛病也很难影响到主历程;如果是多历程的话,可以利用WebView的容器池,有二次秒开的作用;不外缺点就是必要你做好和WebView的跨历程通讯了
  • 网络优化:我们可以让WebView的host和客户端的host保持划一,那么就到达复用DNS缓存的效果;如果客户端有针对网络哀求举行了优化,那么可以让WebView的全部网络哀求托管给客户端
  • H5离线包:这个是手Q的H5方案之一,让客户端提前去下载离线的H5数据包,WebView只必要加载本地H5数据包即可,这么做不但可以制止一些http的挟制,而且跳过了WebView的创建TCP毗连和H5、CCS等数据下载的过程,直接开始UI渲染,大大进步了WebView的效率
1.15 怎样处理处罚大图的加载?

1、起首确定大图的用途,精度需求:


  • 完备表现,对精度要求不高,图片自己就很大
  • 对精度需求比力高,不必要完备表现
2、办理方案


  • 针对第一种的处理处罚图片自己,按需加载(根据表现装备自己巨细举行缩放),低沉精度加载(改变图片模式,如将ARGB8888改成RGB565,ARGB4444),修改图片格式(png改成webp,jpg)
  • 第二种的一样平常接纳局部加载,告急要用到的是BitmapRegionDecoder这个类decodeRegion的方法,读取图片指定巨细的数据,然后通过移动来动态改变表现地域的图片
1.16 谈谈怎样对网络哀求举行优化?


  • 最开始的是DNS,当我们发起一个网络哀求,起告急颠末DNS服务,将域名转化为IP所在,为制止DNS解析非常标题,可以直接利用 IP 创建毗连;
  • 利用 Gzip 压缩 Response 淘汰数据传输量;利用Protocol Buffer 取代 JSON;
  • 哀求图片的 url 中可以添加格式、质量、宽高等参数;利用缩略图、利用WebP格式图片,大图分片传输;
  • 利用网络缓存,利用图片加载框架;
  • 监听装备网络状态,根据差别网络状态选择对应情况下的网络哀求计谋:网络精良和弱网、离线等情况下分别操持差别的哀求计谋,好比 WIFI 下一个哀求可以获取几十个数据,乃至可以一次性执行多个哀求;而弱网下一个哀求获取几个数据,且文本范例优先,富文本其次,除文本数据外别的范例的数据一开始只表现占位符;离线下事先生存哀求数据到磁盘,在离线时从磁盘加载数据。
1.17 请谈谈怎样加载Bitmap并防止内存溢出?

起首我们 要知道Bitmap内存是怎么盘算的例子:
手机屏幕巨细 1080 x 1920(inTarget = 420),加载xhdpi (inDensity = 320)中的图片 1920 x 1080,scale = 420 / 320,最总我们可以得知他的占用内存 1418 * 2520 * 4 很显着 被放大了。
防止内存溢出:


  • 对图片举行内存压缩;
  • 高分辨率的图片放入对应文件夹;
  • 内存复用
  • 实时接纳
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 16:51, Processed in 0.179342 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表