移动Android开发-规范文档

移动Android规范文档

背景:为了统一成都xxx有限公司移动部门的开发规范,特出此文,勿盲目借鉴.

本手册以开发者为中心视角分为 Android 资源文件命名与使用,Android 基本组件,UI与布局,进程、线程与消息通信, 文件与数据库,BitmapDrawable与动画,安全,其他等九大部分,根据约束力强弱, 规约依次分为强制、推荐、参考三大类:

  • 强制】必须遵守,违反本约定或将会引起严重的后果;
  • 推荐】尽量遵守,长期遵守有助于系统稳定性和合作效率的提升;
  • 参考】充分理解,技术意识的引导,是个人学习、团队沟通、项目合作的方 向。

目标是

  • 防患未然,提升质量意识,降低故障率和维护成本;
  • 标准统一,提升协作效率;
  • 追求卓越的工匠精神,打磨精品代码。

注释

强制】类注释

每个类必须严格意义上按照功能注释使用
推荐规则:

/**
*Describe:朝拜时间闹钟界面
*
*Created by zhigang wei
*on 2018/4/18
*
*Company :cpx
*/
强制】方法注释

不是每个一方法都需要注释,但是核心方法必须要注释

  /**
     * 设置数据
     *
     * @param object 设置的数据源
     */
    public void setData(Object... object) {
   

    }
推荐】属性注释

关键属性需要注释,推荐使用第一种

/*倒计时-同时也是判断是否是第一次进入*/
private var clockS: Long = 0x111L

或者

    /**
     * 倒计时-同时也是判断是否是第一次进入
     */
    private var clockS: Long = 0x111L
推荐】功能结构注释

如果一个功能类过于复杂,前期在满足开发任务的前提下需要记录后续优化的注释,后续需及时优化这块逻辑

 /*start------------------倒计时---------------------------*/
	xxx
	xxx
	xxx
  /*end------------------倒计时---------------------------*/
强制README文档注释

每一个独立的module都需要有各自的README文档,介绍项目架构,逻辑处理,核心算法,每一次版本更新到具体内容等

具体格式查看标准示例

Android 资源文件命名与使用

1. 【强制】资源文件需带模块前缀解耦。

在这里插入图片描述

2. 【强制layout 文件的命名方式。
  • Activitylayoutactivity_ 开头
  • Fragmentlayoutfragment_ 开头
  • Dialoglayoutdialog_ 开头
  • includelayoutinclude_ 开头
  • 自定义viewlayoutview_开头
  • ListView 的行 layoutlist_item 开头
  • RecyclerViewitem layoutrecycle_item开头 ;headrecycle_item_head_开头,footerrecycle_item_footer_开头
  • GridView 的行 layoutgrid_item 开头
3.【推荐】Id 资源原则上以驼峰法命名,View 组件的资源 id 需要以 View 的缩写作为 前缀。常用缩写表如下
控件 缩写
LinearLayout ll
RelativeLayout rl
ConstraintLayout cl
ScollView sv
RecyclerView rv
Button btn
ImageView iv
CheckBox cb
RadioButton rb
EditText et
TextView tv

类推其它控件的缩写推荐使用小写字母并用下划线进行分割

但是kotlin使用不需要findview所以也可以采用驼峰命名,个人推荐还是下划线来区分xml

4.【强制】 color 资源使用#AARRGGBB 格式,写入baselib 中colors.xml 文件中
<color name="c_7F000000">#7F000000</color>
5.[强制] 资源文件
  • 自定义点击selector_,自定义点击文字selector_tv,自定义图形shape_统一放入都drawable

  • 点九图都统一放入drawable-xxhdpi

  • 图片分别放入mipmap对应的资源中

  • 其他大文件资源统一放入assets对应类型的文件夹中:例如
    在这里插入图片描述

Android 基本组件

Android 基本组件指 ActivityFragmentServiceBroadcastReceiverContentProvider 等等。

推荐】2018/11/6 补1.constraint-layout

项目中需要定义xml布局文件,根部局推荐使用ConstraintLayout
推荐原因请查看链接

1. 【强制Activity 间的数据通信,对于数据量比较大的,避免使用 Intent + Parcelable的方式,可以考虑 RxBus 等替代方案,以免造成 TransactionTooLargeException
2. 【推荐Activity#onSaveInstanceState()方法不是 Activity 生命周期方法,也不保证 一定会被调用。它是用来在 Activity 被意外销毁时保存 UI 状态的,只能用于保存临 时性数据,例如 UI 控件的属性等,不能跟数据的持久化存储混为一谈。持久化存储 应该在 Activity#onPause()/onStop()中实行。
3.【强制Activity 间通过隐式 Intent的跳转,在发出 Intent之前必须通过 resolveActivity 检查,避免找不到合适的调用组件,造成 ActivityNotFoundException 的异常。

正例:

 public void viewUrl(String url, String mimeType)
    {
   
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse(url), mimeType);
        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ ONLY) != null) {
   
            try {
   
                startActivity(intent);
            } catch (ActivityNotFoundException e) {
   
                if (Config.LOGD) {
   
                    Log.d(LOGTAG, "activity not found for " + mimeType + " over " + Uri.parse(url).getScheme(), e);
                }
            }
        }
    }

反例:

Intent intent = new Intent(); 
intent.setAction("com.great.activity_intent.Intent_Demo1_Result3");
4.【强制】避免在Service#onStartCommand()/onBind()方法中执行耗时操作,如果确 实有需求,应改用IntentService或采用其他异步机制完成。
5.【强制】避免在 BroadcastReceiver#onReceive()中执行耗时操作,如果有耗时工作, 应该创建IntentService完成,而不应该在 BroadcastReceiver 内创建子线程去做。

说明:
由于该方法是在主线程执行,如果执行耗时操作会导致 UI不流畅。可以使用 IntentService 、 创 建 HandlerThread 或 者 调 用Context#registerReceiver (BroadcastReceiver, IntentFilter, String, Handler)方法等方式,在其他 Wroker 线程执行onReceive方法。BroadcastReceiver#onReceive()方法耗时超过 10 秒钟,可能会被系统杀死

6.【强制】避免使用隐式Intent广播敏感信息,信息可能被其他注册了对应 BroadcastReceiverApp接收。

说明:
通过 Context#sendBroadcast()发送的隐式广播会被所有感兴趣的 receiver接收,恶意应用注册监听该广播的receiver可能会获取到Intent中传递的敏感信息,并进行 其他危险操作。如果发送的广播为使Context#sendOrderedBroadcast()方法发送
的有序广播,优先级较高的恶意 receiver 可能直接丢弃该广播,造成服务不可用,或者向广播结果塞入恶意数据。如果广播仅限于应用内,则可以使用 LocalBroadcastManager#sendBroadcast()实现,避免敏感信息外泄和Intent拦截的风险

正例:

Intent intent = new Intent("my-sensitive-event"); 
intent.putExtra("event", "this is a test event");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
 

反例:


Intent intent = new Intent(); 
v1.setAction("com.sample.action.server_running"); 
v1.putExtra("local_ip", v0.h);
context.sendBroadcast(v1);
7. 【推荐 】 添 加 Fragment时 , 确 保 FragmentTransaction#commit()Activity#onPostResume()或者 FragmentActivity#onResumeFragments()内调用。 不要随意使用 FragmentTransaction#commitAllowingStateLoss()来代替,任何 commitAllowingStateLoss()的使用必须经过 code review,确保无负面影响。

说明:
Activity 可能因为各种原因被销毁,Android 支持页面被销毁前通过 Activity#onSaveInstanceState() 保 存 自 己 的 状 态 。 但 如 果
FragmentTransaction.commit()发生在 Activity状态保存之后,就会导致 Activity 重 建、恢复状态时无法还原页面状态,从而可能出错。为了避免给用户造成不好的体验,系统会抛出 IllegalStateExceptionStateLoss 异常。推荐的做法是在Activity 的onPostResume()onResumeFragments()FragmentActivity 里 执 行 FragmentTransaction.commit(),如有必要也可在 onCreate()里执行。不要随意改用FragmentTransaction.commitAllowingStateLoss()或者直接使用 try-catch 避免 crash,这不是问题的根本解决之道,当且仅当你确认Activity重建、恢复状态时,本次 commit 丢失不会造成影响时才可这么做。

8. 【推荐】不要在 Activity#onDestroy()内执行释放资源的工作,例如一些工作线程的 销毁和停止,因为 onDestroy()执行的时机可能较晚。可根据实际需要,在 Activity#onPause()/onStop()中结合isFinishing()的判断来执行。
9. 【推荐】如非必须,避免使用嵌套的 Fragment。可用自定义view替代

Fragment其他注意问题-踩坑纪录点击查看

说明:
嵌套 Fragment 是在 Android API 17 添加到 SDK 以及 Support 库中的功能,
Fragment 嵌套使用会有一些坑,容易出现 bug,比较常见的问题有如下几种:

  1. onActivityResult()方法的处理错乱,内嵌的 Fragment 可能收不到该方法的回调,需要由宿主 Fragment 进行转发处理;
  2. 突变动画效果;
  3. 被继承的 setRetainInstance(),导致在 Fragment 重建时多次触发不必要的逻辑。
10【推荐】总是使用显式Intent启动或者绑定Service,且不要为服务声明IntentFilter, 保证应用的安全性。如果确实需要使用隐式调用,则可为 Service 提供 Intent Filter 并从 Intent 中排除相应的组件名称,但必须搭配使用 Intent#setPackage()方法设置 Intent 的指定包名,这样可以充分消除目标服务的不确定性。
11.【推荐】Service 需要以多线程来并发处理多个启动请求,建议使用 IntentService, 可避免各种复杂的设置。
12.【推荐】对于只用于应用内的广播,优先使用LocalBroadcastManager 来进行注册 和发送,LocalBroadcastManager 安全性更好,同时拥有更高的运行效率

正例:
对于使用 Context#sendBroadcast()等方法发送全局广播的代码进行提示。如果该广播仅用于应用内,则可以使用 LocalBroadcastManager 来避免广播泄漏以及广播被拦截等安全问题,同时相对全局广播本地广播的更高效。

13【推荐】当前 Activity 的 onPause 方法执行结束后才会执行下一个 Activity 的 onCreate 方法,所以在 onPause 方法中不适合做耗时较长的工作,这会影响到页面之间的跳 转效率。
14.【强制】不要在 Android 的 Application 对象中缓存数据。基础组件之间的数据共享 请使用 Intent 等机制,也可使用 SharedPreferences 等数据持久化机制,大量数据可以采用数据库持久化方案。
15.【推荐】使用 Toast 时,建议定义一个全局的 Toast 对象,这样可以避免连续显示 Toast 时不能取消上一次 Toast 消息的情况(如果你有连续弹出 Toast 的情况,避免 使用 Toast.makeText)。
16.【强制】使用 Adapter 的时候,如果你使用了 ViewHolder 做缓存,在 getView()的 方法中无论这项 convertView 的每个子控件是否需要设置属性(比如某个 TextView 设置的文本可能为 null,某个按钮的背景色为透明,某控件的颜色为透明等),都需 要为其显式设置属性(Textview 的文本为空也需要设置 setText(""),背景透明也需要 设置),否则在滑动的过程中,因为 adapter item 复用的原因,会出现内容的显示错 乱。
  • 9
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值