前言一个合格的代码不仅要满足于实现功能,还要遵循好的规范。遵循良好的代码规范有利于:提高程序稳定性,减少代码量减少隐患,降低故障率;增强可扩展性,大大提高维护效率;统一标准,提高多人协作效率;方便新人快速上手,项目组成员变动时保证项目进度。这里总结一下Android开发过程中需要注意的一些要点,包括多个部分,根据绑定力的强弱分为两类:Mandatory:如果不遵守,会导致代码混乱严重,后期维护复杂,甚至出现严重bug;建议:不遵守可能会导致代码描述不清,理解困难,出现功能多、维护难的问题。以下是标准文本系统的强制性设计:不允许出现两个相同的逻辑块,必须提取为公共方法,差异由参数控制,避免修改时多次修改造成遗漏;两个相同的逻辑块不允许在同一个逻辑组中复杂的布局必须提取为单独的包含/合并;父类中不允许有子类特有的方法,必要时父类可以定义抽象方法并由子类实现;Activity中多个Fragment之间不允许直接通信通信必须通过Activity中转。推荐:推荐MVP或MVVM架构;推荐使用Kotlin语言;采用模块分类方式代替文件分类方式,方便快速查找模块相关内容,例如:LoginActivity/LoginPreenter/LoginHttpRequest/LoginBean/LoginAdapter等属于同一个登录模块文件文件夹,而不是将所有活动放在一个文件夹中,并将所有适配器放在一个文件夹中。强制命名方式:不允许使用中文命名方式;java/kotlin文件使用大驼峰命名法,例如:LoginActivity.kt,NewsAdapter.kt,NewsBean.java;layout/drawable/anim/style等资源文件使用小写+下划线,示例:login_activity.xml、login_logo.png;类定义使用大驼峰命名法,例如:classLoginPresenter{},classNewsBean{};对象使用小驼峰命名法,例如:LoginPresenterloginPresenter,NewsBeannewsBean;静态常量使用全大写+下划线的方式,例子:publicstaticfinalbooleanIS_RELESAE=true;Kotlin使用的布局中的控件id必须使用小驼峰大小写,例如:android:id="@+id/tvLogin"。建议:命名文件/资源??时使用module+type,以便快速找到相关内容,比如登录页面:LoginActivity.kt、login_activity.xml、login_logo.png、网络错误、#f3f3f3所用layouts中id名称的建议java使用小驼峰式,以控件类型缩写开头,例如:android:id="@+id/tvLogin",附录常用控件缩写:Visibilityenforcement:Allnewdefinedclasses/methodsarewrittenasprivateby默认情况下,只有在其他类需要被引用时,才会视情况标记为public、protected、package-private;建议:如果java定义的父类中定义的方法子类重写会出问题,加final关键字;注释相关的类/复杂的或者不能从方法名中看出意图的方法必须添加注释。在给类/方法添加注解时,必须使用这种类型的注解:/***CreatedbyXXXon2019/6/19.*描述这种类型的功能,用复杂的逻辑解释主要思想*/publicclassLoginPresenter{/***fornetworkrequests*@paramsxxxXXX*/publicvoiddoLoginRequest(...){}}变量注解不允许使用与类/方法一致的注解;@params、@不允许出现在方法注解中,return的参数描述错误情况,必须实时更新;推荐:一段逻辑建议使用/**/方法;方法/参数建议添加@Nullable、@NotNull、@UiThread等注解;代码风格同时存在于该git目录下AndroidCodeStyleSetting.jar配置文件,用于在导入AndroidStudio后以统一风格格式化代码。如果你在写代码的时候没有随时格式化代码的习惯,可以在AndroidStudio版本控制提交窗口右侧的BeforeCommit中勾选Reformatcode选项。Android基础组件强制:Intent通信不允许传输超过1M的数据,可以使用外部Presenter传输或者EventBus传输;Intent在隐式启动时必须检查目标是否存在,否则会出现找不到目标的crash折叠:if(getPackageManager().resolveActivity(intent,PackageManager.MATCH_DEFAULT_ONLY)!=null);如果Activity/Service/BroadcastReceiver中有耗时操作,则必须采用多线程处理;应用在内部发送广播时,只能使用LocalBroadcastManager.getInstance(this).sendBroadcast(intent),不允许使用context.sendBroadcast(intent),避免外部应用拦截;不允许在Application中缓存数据,全局共享数据可以存储在presenter中,也可以使用SharedPreference读写;在Activity或Fragment中动态注册BroadCastReceiver时,registerReceiver和unregisterReceiver必须成对出现;建议:结合Activity#onPause/onStop中isFinishing的判断执行释放资源,一定不要放在Activity#onDestroy()中执行时间较晚的Activity#onPause中执行;不要在Activity#onPause中执行耗时操作,会导致界面跳转卡顿,可以在Activity#onStop中执行;UI/LayoutMandatory:布局xml首选ConstraintLayout,可以保证无嵌套完成99%的布局需求,包括部分控件的同时显示和隐藏需求;不允许用ScrollView包裹ListView/GridView/ExpandableListVIew等列表View,复杂的多项式列表可以用多个ItemType处理;建议:在Activity中显示对话框或弹出浮层时,尽量使用DialogFragment而不是Dialog/AlertDialog,这样便于随Activity生命周期一起管理弹窗的生命周期;进程/线程/消息推送是强制性的:当有多个进程时,Application中的初始化代码应该根据进程分别处理,避免不必要的业务初始化;创建新线程时,它必须通过该行进程池的方法不允许使用newThread()方法;在Activity/Fragment中使用Handler时,必须使用静态内部类+WeakReferences方法或者在onStop中调用handler.removeCallbacksAndMessages;建议:使用ContentProvider而不是在多个进程之间共享数据SharedPreferences#MODE_MULTI_PROCESS;文件/数据库强制:使用系统API获取文件路径,避免手写字符串,示例:android.os.Environment#getExternalStorageDirectory(),Context#getFilesDir(),错误示例:Filefile=newFile("/mnt/sdcard/下载/相册",名称);使用外部存储时,必须检查外部存储的可用性:Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());DatabaseCursor使用后必须关闭,避免内存泄露;建议:SharedPreference只存储简单数据类型,不存储复杂数据,如json数据/Bitmap编码等;为SharedPreference提交数据时,尽量使用Editor#apply()而不是Editor#commit();image/animationmandatory:loadlarge图片必须在子线程处理,否则UI会卡顿;在Activity.onPause()/onStop()中关闭当前activity正在执行的动画;推荐:安卓图片推荐转成WebP格式,可以减少APK体积;动画尽量不要使用AnimationDrawable,占用内存大;使用ARGB_565而不是ARGB_888以减少内存使用;动画执行结束,调用View.clearAnimation()释放相关资源;安全强制:在线包必混淆;加解密key/salt不允许硬编码到代码中,防止反编译获取;https处理证书必须经过验证,任何证书都不允许直接接受;使用Android的AES/DES/DESede加密算法时,不要使用默认的加密方式ECB,要指定CBC/CFB加密方式;禁止将敏感信息打印到日志中;确保应用程序发布时android:debuggable为false;必须使用X509TrustManager子类中的checkServerTrusted函数来验证服务器端证书的有效性,并且必须将android:allowbackup属性设置为false以防止adbbackup导出应用数据
