Android 项目优化(七):阿里巴巴Android开发手册整理总结
本来之前觉得Android项目优化系列的文章基本整理完毕了,但是近期看了一下《阿里Android开发手册》有了很多收获,想再整理一篇,下面就开始吧。
先在这里列一下之前整理的文章及链接:
一、Android 基本组件开发规范
1. Activity 开发
必须要遵守的开发规范如下:
a). Activity 间数据通信,对于数据量比较大的,避免使用Intent + Parcelable的方式,可以考虑使用EventBus等替代方案,以免造成TransactionTooLargeException异常。
b). Activity 间通过隐式的Intent跳转,在Intent发出去之前必须使用resolveActivity检查,避免找不到合适的调用组件,造成ActivityNotFoundException异常。
c). Activity 动态注册BroadCastReceiver时,registerReceiver和unregisterReceiver方法要成对出现,且生命周期对应。(否则会导致内存泄漏,部分华为机型对receiver进行资源管控,单个应用注册过多receiver会触发管控模块抛出异常,可能会导致应用崩溃。)
建议的遵守的开发规范如下:
a). 不要在Activity的onDestroy()内执行释放资源的工作,例如一些工作线程的销毁和停止。因为onDestroy执行的时机可能较晚了,可以根据时机需要在Activity的onPause或onStop方法中结合isFinishing来判断执行相应的逻辑。
b). 当前Activity的onPause方法执行结束后才会创建(onCreate)或恢复(onRestart)别的Activity,所以在onPause方法中不适合做耗时较长的操作,耗时较长的操作会影响页面之间的跳转效率。
c). Activity的onSaveInstanceState方法不是Activity生命周期方法,也不保证一定会被调用。它是用来在Activity被意外销毁时保存UI状态的,只能用于保存临时数据,例如UI控件的属性,不能用于数据持久化的存储控制。持久化存储应该在Activity的onPause/onStop中实行。
2. Service 开发
必须要遵守的开发规范如下:
a). 避免在Service的onStartCommand/onBind方法中执行耗时操作,如果确实有需求,应改为IntentService或者采用其他异步机制完成。
建议的遵守的开发规范如下:
a). Service需要以多线程并发处理多个启动请求,建议使用IntentService,可避免各种复杂的配置。
b). 建议总是使用显式的Intent启动或者绑定Service,且不要为Service声明Intent Filter,保证应用的安全性。如需要隐式调用,建议设置Intent的指定包名,这样可以充分消除目标Service的不确定性。
3. BroadCastReceiver开发
必须要遵守的开发规范如下:
a). 避免在BroadCastReceiver的onReceive方法中执行耗时操作,如果有耗时工作,应该创建IntentService完成,而不应该在BroadCastReceiver内创建子线程去做。
b). 避免使用隐式的Intent广播敏感信息,信息可能被其他注册了对应的BroadCastReceiver的App接收。如果广播仅限于应用内,可使用LocalBroadcastManager的sendBroadcast实现,避免敏感信息外泄和Intent拦截的风险。
建议的遵守的开发规范如下:
a). 对于只用于应用内的广播,优先使用LocalBroadcastManager来注册和发送,LocalBroadcastManager安全性更好,能避免敏感信息外泄和Intent拦截的风险,同时拥有更高的运行效率。
二、UI 与 布局开发规范
必须要遵守的开发规范如下:
a). 布局中不得不使用ViewGroup多重嵌套时,不要使用LinearLayout嵌套,改用RelativeLayout,可以降低嵌套层数。
说明:Android 应用页面的任何一个View都需要经过measure、layout、draw三个步骤才能被正确的渲染。嵌套层级越多,带来的measure次数越多,计算就会越费时。
b). 不要在非UI线程进行View相关的操作。
c). 不能用ScrollView包裹ListView/GridView/ExpandableListView,因为这样会把ListView的所有Item都加载到内存中,需要消耗巨大的内存和CPU去绘制画面。这里推荐使用NestedScrollView。
d). 在使用Adapter的时候,如果你使用了ViewHolder做缓存,在getView()的方法中,无论这项convertView的每个子控件是否需要设置属性,都要显式的设置属性(包括文本内容、背景色及其他属性),否则在滑动中,因为adapter item复用的原因,会出现内容的显示错乱。
建议的遵守的开发规范如下:
a). 在Activity中显示对话框或弹出浮层时,尽量使用DialogFragment,而非Dialog/AlertDialog,这样便于随Activity生命周期管理对话框/弹出浮层的生命周期。
b). 推荐文本大小使用:dp单位。推荐View大小使用:dp单位。因为:sp是Android早期推荐使用的,但sp即受屏幕密度影响又受到系统字体设置影响,dp相对能保证UI的一致性。
c). 尽量避免在Activity没有完全显示时显示PopupWindow和Dialog。
d). 尽量不要用AnimationDrawable实现帧动画(尤其图片多的时候),它在初始化时会将所有图片加载到内存,非常消耗资源(低端机可能直接OOM),且不能释放,释放后下次加载会报错。
三、进程、线程与消息通信开发规范
必须要遵守的开发规范如下:
a). 不要通过Intent在Android基础组件之间传递大数据,否则可能会导致OOM。
b). 在Application的业务初始化代码加入进程判断,确保只在自己需要的进程初始化。特别是后台进程减少不必要的业务初始化。
c). 新建线程时,必须通过线程池提供(AsyncTask或者ThreadPoolExecutor或者其他形式的线程池),不允许在应用中自行创建线程。
说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致内存消耗完或者过度切换的问题。另外,创建匿名线程不便于后续的资源使用的分析,对性能分析会造成困扰。
d). 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的方式能够让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
e). 子线程中不能更新界面,更新界面必须在主线程中进行,网络操作不能在主线程中调用。
建议的遵守的开发规范如下:
a). 尽量减少不同App之间的进程通信及拉起行为。拉起会导致占用系统资源,影响用户体验。
b). 新建线程时,定义能识别自己业务的线程名称,便于性能优化和问题排查。
c). 使用线程池是,在业务满足的情况下尽量设置线程的存活时间(setKeepAliveTime),确保线程空闲时能够被释放。
d). 尽量避免在多进程之间用SharePreferences共享数据,虽然可以通过设置MODE_MULTI_PROCESS来实现,但是这种方式官方已经不推荐使用了。
e). 谨慎使用Android的多进程,虽然多进程能降低主进程的压力,但是需要注意以下问题:
- 首次进入新启动进程的页面会有延迟现象(可能黑屏or白屏几秒)。
- 应用内多进程时,Application实例化多次,需要考虑各个模块是否需要在所有进程中初始化。
四、文件与数据库开发规范
必须要遵守的开发规范如下:
a). 任何时候都不要硬编码文件路径,请使用Android文件系统API访问(硬编码存在机型兼容问题)。
b). 当使用外部存储时,必须检查外部存储的可用性。
c). 应用间共享文件时,不要通过放宽文件系统的权限去实现,而是应该使用FileProvier。
d). 数据库Cursor必须确保使用完后关闭,以避免内存泄漏。
e). 多线程写入数据库时,需要使用事务,以免出现同步问题。
f). 执行SQL时,应该使用SQLiteDataBase的insert、update、delete方法,不要使用execSQL方法,以免SQL注入风险。
g). 如果ContentProvider管理的数据存储在SQL数据库中,应该避免将不受信任的外部数据直接拼接在原始SQL语句中。
建议的遵守的开发规范如下:
a). SharePreference中只能存储简单数据类型(int、boolean、String等),复杂数据类型建议使用文件、数据库等其他存储方式。
b). SharePreference提交数据时,尽量使用apply方法。除非需要确定提交结果,并据此执行后续操作时,才使用commit方法。
c). 将大数据写入数据库时,请使用事务或者其他能提高I/O效率的机制,保证执行速度。
五、Bitmap、Drawable与动画
必须要遵守的开发规范如下:
a). 加载大图或者一次性加载多张图的时候,应该在异步线程中进行。图片的加载,涉及IO操作,以及CPU密集操作,很可能引起卡顿。
b). 在ListView、ViewPager、RecyclerView、GridView等组件中使用图片时,应做好图片的缓存,避免使用持有图片导致内存溢出,也要避免重复创建图片,引起性能问题。推荐使用Fresco、Glide等图片加载库。
c). 在Activity的onPause方法或onStop方法中,关闭当前Activity正在执行的动画。
建议的遵守的开发规范如下:
a). 推荐根据展示实际需要,压缩图片,而不是直接展示原图,这样能提高App的性能。
b). 使用完毕的图片,应及时回收,释放宝贵的内存。(2.3.3及以下版本需要调用recycle方法,2.3.3以上GC会自动管理不需要调用recycle方法)
c). 在动画或者其他异步任务结束时,应考虑回调时刻的环境是否还支持业务处理,并增加相关的空指针等判断逻辑。
d). 谨慎使用Gif,注意限制每个页面同时允许播放的gif图片数量,以及单个gif图片的大小。
e). 根据设备性能,选择性的开启复杂动画,以实现一个整体较优的性能和体验。
六、安全
必须要遵守的开发规范如下:
a). 将android:allowbackup属性必须设置为false,防止应用数据被导出。
说明:android:allowbackup 是Android提供的adb调试功能,如果设置为true,可以导出应用数据并在任意设备上恢复。这会对应用安全性和用户数据隐私构成极大的威胁,所以必须设置为false,防止数据泄漏。
b). 在SDK支持的情况下,Android必须使用v2签名,这将对APK文件的修改做更多的保护。
c). 所有的Android基本组件(Activity、Service、BroadcastReceiver、ContentProvider等)都不应在没有严格权限控制的情况下,将android:exported设置为true。
d). 确保应用发布的版本的android:debuggable属性设置为true。
建议的遵守的开发规范如下:
a). 在Android 4.2以上,对安全性较高的应用可在Activity中,对Activity所关联的Window应用WindowManager.LayoutParams.FLAG_SECURE,防止被截屏、录屏。对于其他的Window的窗口,如Dialog、DialogFragment等,根据需要也进行相应的保护。
Android 项目优化(七):阿里巴巴Android开发手册整理总结的更多相关文章
- Android 项目优化(一):项目代码规范优化
项目代码规范为主要包含:类,常量,变量,ID等命名规范:注释规范:分包规范:代码风格规范. 项目代码规范是软件开发过程中非常重要的优化环节. 目前的开发社区提供了很多的开发规范文档,阿里巴巴推出了&l ...
- Android 项目优化(五):应用启动优化
介绍了前面的优化的方案后,这里我们在针对应用的启动优化做一下讲解和说明. 一.App启动概述 一个应用App的启动速度能够影响用户的首次体验,启动速度较慢(感官上)的应用可能导致用户再次开启App的意 ...
- 阿里巴巴Java开发手册———个人追加的见解和补充(一)
先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...
- 读阿里巴巴Java开发手册v1.2.0之工程结构有感【架构篇】
首先,把昨天那俩条sql语句的优化原因给大家补充一下,第一条效率极低,第二条优化后的,sql语句截图如下: 经过几个高手的评论和个人的分析: 第一条sql语句查询很慢是因为它首先使用了in关键字查询, ...
- 阿里巴巴 Java 开发手册评述
http://blog.jobbole.com/110427 阿里巴巴Java开发手册(终极版)https://pan.baidu.com/s/1c1UQM7Q 阿里巴巴Java开发规约插件p3cGi ...
- 304902阿里巴巴Java开发手册1.4.0
转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...
- 阿里巴巴 Java 开发手册 1.4.0
一.编程规约(一) 命名风格1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $name / name_ / name$ ...
- 阿里巴巴Java开发手册评述
2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...
- 阿里巴巴Java开发手册快速学习
Java作为一门名副其实的工业级语言,语法友好,学习简单,大规模的应用给代码质量的管控带来了困难,特别是团队开发中,开发过程中的规范会直接影响最终项目的稳定性. 善医者“未有形而除之”,提高工程健壮性 ...
随机推荐
- Logistic回归算法梯度公式的推导
最近学习Logistic回归算法,在网上看了许多博文,笔者觉得这篇文章http://blog.kamidox.com/logistic-regression.html写得最好.但其中有个关键问题没有讲 ...
- Java 理论与实践: 处理 InterruptedException【转】
这样的情景您也许并不陌生:您在编写一个测试程序,程序需要暂停一段时间,于是调用Thread.sleep().但是编译器或 IDE 报错说没有处理检查到的InterruptedException.Int ...
- Spring(Bean)5
spel <bean id="address" class="com.atguigu.spring.beans.spel.Address"> < ...
- MySQL多索引查询选择
MySQL多索引查询选择 MySQL选择索引-引入 我们知道我们一个表里面可以有多个索引的,那么我们查询数据的时候不指定索引,MySQL就会帮我们自动选择.既然是MySQL程序帮我们自动选择的那么会不 ...
- Django-settings可插拔实现
Setting可插拔 django暴露了一个可以给用户自定义配置的文件,优先使用用户配置的信息,而且必须要大写才有效 文件目录 --about_settings --default --conf -- ...
- python-模块,异常,环境管理器
模块 Module 什么是模块: 1.模块是一个包含有一系列数据,函数,类等组成的程序组 2.模块是一个文件,模块文件名通常以.py结尾 作用: 1.让一些相关数据,函数,类等有逻辑的组织在一起,使逻 ...
- 深入浅出-iOS程序性能优化
iOS应用是非常注重用户体验的,不光是要求界面设计合理美观,也要求各种UI的反应灵敏,我相信大家对那种一拖就卡卡卡的 TableView 应用没什么好印象.还记得12306么,那个速度,相信大家都受不 ...
- Netty学习——服务器端代码和客户端代码 原理详解
服务器端代码和客户端代码 原理详解:(用到的API) 0.Socket 连接服务器端的套接字 1.TcompactProtocol 协议层2.TFrameTransport 传输层3.THsh ...
- 第三章 学习Shader所需的数学基础(4)
法线变换 法线(normal),也被称为法矢量(normal vector).在以前我们已经讲过如何使用变换矩阵来变换一个顶点或方向矢量,但法线是需要我们特殊处理的一种方向矢量.在游戏中,模型的顶点往 ...
- 给各位PHP程序员十点未来的建议
PHP 从诞生到现在已经有20多年历史,从Web时代兴起到移动互联网退潮,互联网领域各种编程语言和技术层出不穷, Node.js . GO . Python 不断地在挑战 PHP 的地位.这些技术的推 ...