直入主题吧......
问题一 :adapter嵌套adapter
**eg :一个listView 中 已经使用了adapter, 然而这个adapter 中根据type类型不同,在某一个type 的ViewHolder 的 bindData中又加载一个listView,从而再嵌套了一个adapter;
****实测,在华为android 7及以下低版本滑动会有卡顿,
**解决方法:尽量使用一个ListView ,一个adapter, 通过增加type 类型来满足加载不同的item条目
问题二 :XML布局嵌套层级过深
由android view 的绘制流程,
-
Measure:测量视图大小。从顶层父View到子View递归调用measure方法,measure方法又回调OnMeasure。
-
Layout:确定View位置,进行页面布局。从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上。
-
Draw:绘制视图。ViewRoot创建一个Canvas对象,然后调用OnDraw()。六个步骤:①、绘制视图的背景;②、保存画布的图层(Layer);③、绘制View的内容;④、绘制View子视图,如果没有就不用;⑤、还原图层(Layer);⑥、绘制滚动条。
如果 在上面某一个流程耗时过多,超过16ms就会出现明显的卡顿现象
1、尽量使用MeasureSpec.EXACTLY精确值,比如match_parent 或具体的数值(xx dp)
2、减少层级嵌套,推荐用androidx 提供的ConstraintLayout约束者布局
3、使用比例,来动态适配宽高比
问题三 :精准导向,可控性
1、adapter 调用notifyDataSetChanged 是一种非常粗暴的行为,如果条目数量过多会很浪费性能,同时体验也不好;所以若你只修改了整个ListView 中的某一个条目,建议只刷新该条目即可,节省性能。
2、模块,组件之间发消息的时候,建议加上type 来区分消息的类型,缩小消息的接收者的范围;因为有可能,这个消息有许多的监听者,如果你不区分,那么这些监听者都会去执行相应的逻辑,从而导致性能浪费,同时也会有出乎预期的问题
问题四 :编码的缺陷导致
1、代码反复判空,导致代码执行一些无用的操作,影响优雅性,同时造成代码冗余,降低维护性,增加编码成本,冗余代码达到一定量级也会拖慢代码运行效率
建议合理设计代码,kotlin 的闭包模式十分不错,外层判断了非空性,内部可以省去很多判空代码处理
2、编码问题导致的内存泄漏;
1)不要滥用匿名内部类,很容易导致内存泄漏,当泄漏达到一定的量级,会OOM;
建议使用静态内部类,或使用弱引用,软引用,持有的引用在onDestory中及时销毁,或直接持有application
2)SVGA在使用的时候,如果不及时释放资源,会导致内存抖动,乃至内存溢出;
建议,1、SVGA增加本地缓存, 2、SVGA在 detach()的时候及时清空画布
3)Bitmap大图加载导致内存溢出等问题,建议使用Glide成熟框架;
问题五 :代码不规范,结构性差,导致维护性低,容易使编码人员犯错
ps :首先建议使用kotlin,提高开发效率,提高安全性,比原有java 编写 会减少大量代码
1、设计一个好的架构很重要,无论MVC,MVP,MVVM, 各有优劣,但是万变不离其宗,需要设计好的架构,成熟架构,家庭端采用的是MVVM
2、代码命名规范,无论变量还是函数还是类名,资源名称,模块名称都需要有规范,做到见名知意,杜绝中文或符号!
3、控制每个类,每个函数的规模,如果函数功能过于复杂,可以多抽取几个,同理类也是一样
4、每个类或函数做到功能单一,注意代码复用,抽取公共组件,公共lib 库来提供能力
5、利用好继承和多态的特性,抽取公共能力到父类,到基类;每个基类层级做到功能单一
6、设计模式的使用可以大大优化代码的可读性,提高代码的优雅性;比如工厂,建造者,观察者,单例等
7、降低代码的耦合性,模块化和组件化是必须的。(Arouter 阿里开源路由框架)
同时Activity 和 Fragment 之间通信,尽量做到,Fragment 不要通过getActivity()来获取宿主Activity的引用,建议通过注册监听的传入引用的方式,这样,当Fragment销毁的时候可以释放引用,避免内存泄漏
8、公共能力归一;比如音视频能力,音频和视频可以共用一套控制ExoPlayer(谷歌提供的一个开源播放器)的逻辑,通过判断是否是音频或者视频,来觉得是否需要传入SurfaceView,通过是否需要同时使用多个音源,来开启多个ExoPlayer
但是管理控制的入口是唯一的;
9、控制资源大小;
1) 比如合理利用hdpi, xhdpi, xxhdpi,xxxhdpi ;对于无关紧要的占位图,只要不影响用户识别关键信息,不影响美观,可以只放入 hdpi,xhdpi
2)图片需要压缩后再使用,我们需要从源头开始控制apk包的体积,如果apk 体积过大,将来万一出海,海外东南亚,非洲等国家的低端手机可能只有512M, 你一个apk 就干掉人家大半或全部内存。。。。
推荐使用SVG矢量图的图片,如果实在不行再用png,jpg,建议UI同学提升技能啊!!
3)so, 第三方aar,jar 引入包控制大小,如果依赖小,建议部分源码引入
10、增加问题的监控手段
如:bugly, leakcary,发现问题,及时解决问题~