android adapter 按钮隐藏 第一个无效_Android开发规范

本文详细介绍了Android开发中的命名规范、资源文件命名规则、基础组件使用建议,强调了UI布局和Adapter的最佳实践,以及进程、线程、文件、数据库和安全方面的注意事项。特别提醒在Adapter中使用ViewHolder时,即使内容为空也要为每个子视图显式设置属性,以防止显示混乱。此外,还提出了关于避免内存泄漏、提高应用安全性和性能优化等多个方面的重要指导。
摘要由CSDN通过智能技术生成

注释

类/复杂或者不能从方法名字看出意图的方法必须添加注释

/**
* @Author: LiuJinYang
* @CreateDate: 2020/5/16 9:32
* 网络请求工具类
*/
public class RetrofitUtil {
/**
* 添加公参basic
*
* @param key 公参字段名
* @param value 公参值
*/
public void addBasic(String key, String value) {
basicMap.put(key, value);
}
}

命名

  • 类命名,类文件名使用 UpperCameCase 风格, 必须遵从驼峰形式, 且要保证从类的名称上能区分出它是什么功能类型;

  • 方法名第一个单词要体现出方法的功能 例如:save, set, get, insert, create;

  • 对象使用小驼峰方式, 例: LoginPresenter loginPresenter, NewsBean newsBean;

  • 全局变量和局部变量功能相同时:全局加 “m”。参数名,可以和成员变量名相同,但要注意引用成员变量时,需要加上 this 字段

  • 常量:全部大写,单词之间使用 “_” 分隔。

  • 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文方式;正确的英文拼写和语法可以让阅读者易于理解, 避免歧义。纯拼音命名方式也不要使用。

  • 抽象类命名使用 Abstract 或者 Base 开头,异常类命名使用 Exception 结尾;测试类以他要测试的类的名称开始,以 Test 结束。

资源文件命名
  1. layout文件命名:

Activity 的 layout 以 module_activity 开头
Fragment 的 layout 以 module_fragment 开头
Dialog 的 layout 以 module_dialog 开头
include 的 layout 以 module_include 开头
ListView 的行 layout 以 module_list_item 开头
RecyclerView 的 item layout 以 module_recycle_item 开头
GridView 的 item layout 以 module_grid_item 开头
  1. drawable命名:

模块名_业务功能描述_控件描述_控件状态限定词, 如:module_login_btn_pressed,module_tabs_icon_home_normal

  1. anim 命名:

模块名_逻辑名称_[方向|序号],如 module_fade_in , module_fade_out , module_push_down_in

  1. color命名:

模块名_逻辑名称_颜色,如:#33b5e5e5

  1. dimen 命名:

模块名_描述信息,如:1dp

  1. string 命名:

模块名_逻辑名称,如:moudule_login_tips,module_homepage_notice_desc

  1. id 命名:

推荐使用小写字母并用下划线进行分割,View 组件的资源 id 建议以 View 的缩写作为前缀。常用缩写表如下:

LinearLayout  ll
RelativeLayout rl
ConstraintLayout cl
ListView lv
ScollView sv
TextView tv
Button btn
ImageView iv
CheckBox cb
RadioButton rb
EditText et

Android 基本组件

Android 基 本 组 件 指 Activity 、 Fragment 、 Service 、 BroadcastReceiver 、ContentProvider 等等。

  1. Activity 间的数据通信, 对于数据量比较大的,避免使用 Intent + Parcelable的方式,可以考虑 EventBus/RxBus 等替代方案,以免造成 TransactionTooLargeException。

  2. Activity 间通过隐式 Intent 的跳转,在发出 Intent 之前必须通过 resolveActivity检查,避免找不到合适的调用组件,造成 ActivityNotFoundException 的异常。

  3. 避免在 Service#onStartCommand()/onBind()方法中执行耗时操作,如果确 实有需求,应改用 IntentService 或采用其他异步机制完成。

  4. 避免在 BroadcastReceiver#onReceive()中执行耗时操作,如果有耗时工作, 应该创建 IntentService 完成,而不应该在 BroadcastReceiver 内创建子线程去做。

  5. 避免使用隐式 Intent 广播敏感信息,信息可能被其他注册了对应 BroadcastReceiver 的 App 接收。

  6. 对于只用于应用内的广播,优先使用 LocalBroadcastManager 来进行注册 和发送,LocalBroadcastManager 安全性更好,同时拥有更高的运行效率。

  7. Activity或者Fragment中动态注册BroadCastReceiver时,registerReceiver() 和 unregisterReceiver()要成对出现。

  8. 不要在 Activity#onDestroy()内执行释放资源的工作,例如一些工作线程的 销毁和停止,因为 onDestroy()执行的时机可能较晚。可根据实际需要,在Activity的onPause()/onStop()中结合 isFinishing()的判断来执行。

  9. 当前 Activity 的 onPause 方法执行结束后才会创建(onCreate)或恢复 (onRestart)别的 Activity,所以在 onPause方法中不适合做耗时较长的工作,这会影响到页面之间的跳转效率。

  10. Service 需要以多线程来并发处理多个启动请求,建议使用 IntentService, 可避免各种复杂的设置。

UI 与布局

  • 布局xml优先使用ConstraintLayout, 可以保证无嵌套的情况下完成包括部分控件同时显隐需求在内的99%的布局要求;

  1. 布局中不得不使用 ViewGroup 多重嵌套时,不要使用 LinearLayout 嵌套, 改用 RelativeLayout,可以有效降低嵌套数。

  2. 在 Activity 中显示对话框或弹出浮层时,尽量使用 DialogFragment,而非 Dialog/AlertDialog,这样便于随Activity生命周期管理对话框/弹出浮层的生命周期。

  3. 禁止在非 UI 线程进行 View 相关操作。

  4. 禁止在设计布局时多次为子 View 和父 View 设置同样背景进而造成页面过 度绘制,推荐将不需要显示的布局进行及时隐藏。

  5. 不能使用 ScrollView 包裹 RecyclerView/ListView/GridView/ExpandableListVIew;因为这 样会把 ListView 的所有 Item 都加载到内存中,要消耗巨大的内存和 cpu 去绘制图面。

  6. 不要在 Android 的 Application 对象中缓存数据。基础组件之间的数据共享 请使用 Intent 等机制,也可使用 SharedPreferences 等数据持久化机制。

  7. 使用 Adapter 的时候,如果你使用了 ViewHolder 做缓存,在 getView()的 方法中无论这项 convertView 的每个子控件是否需要设置属性(比如某个 TextView 设置的文本可能为 null,某个按钮的背景色为透明,某控件的颜色为透明等),都需 要为其显式设置属性(Textview 的文本为空也需要设置 setText(""),背景透明也需要 设置),否则在滑动的过程中,因为 adapter item 复用的原因,会出现内容的显示错 乱。

进程、线程与消息通信

  1. 不要通过 Intent 在 Android 基础组件之间传递大数据(binder transaction 缓存为 1MB),可能导致 OOM。

  2. 在 Application 的业务初始化代码加入进程判断,确保只在自己需要的进程 初始化。特别是后台进程减少不必要的业务初始化。

public class MyApplication extends Application {
@Override
public void onCreate() {
//在所有进程中初始化
....
//仅在主进程中初始化
if (mainProcess) {
...
}
//仅在后台进程中初始化
if (bgProcess) {
...
}
}
}
  1. 新建线程时,必须通过线程池提供(AsyncTask 或者 ThreadPoolExecutor 或者其他形式自定义的线程池),不允许在应用中自行显式创建线程。

  2. 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方 式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

  3. 子线程中不能更新界面,更新界面必须在主线程中进行,网络操作不能在 主线程中调用。

  4. 新建线程时,定义能识别自己业务的线程名称,便于性能优化和问题排查。

public class MyThread extends Thread {
public MyThread(){
super.setName("ThreadName");

}
}
  1. ThreadPoolExecutor 设置线程存活时间(setKeepAliveTime),确保空闲时 线程能被释放。

  2. 禁 止 在 多 进 程 之 间 用 SharedPreferences 共 享 数 据 , 虽 然 可 以(MODE_MULTI_PROCESS,已过时),但官方已不推荐。

  3. 谨慎使用 Android 的多进程,多进程虽然能够降低主进程的内存压力,但 会遇到如下问题:

    1. 首次进入新启动进程的页面时会有延时的现象(有可能黑屏、白屏几秒,是白屏还是黑屏和新 Activity 的主题有关);

    2. 应用内多进程时,Application实例化多次,需要考虑各个模块是否都需要在所有进程中初始化。

文件与数据库

  1. 任何时候不要硬编码文件路径,请使用 Android 文件系统 API 访问。

  2. 当使用外部存储时,必须检查外部存储的可用性。

  3. 应用间共享文件时,不要通过放宽文件系统权限的方式去实现,而应使用 FileProvider。

  4. SharedPreference 中只能存储简单数据类型(int、boolean、String 等), 复杂数据类型建议使用文件、数据库等其他方式存储。

  5. 数据库 Cursor 必须确保使用完后关闭,以免内存泄漏。

  6. 多线程操作写入数据库时,需要使用事务,以免出现同步问题。

  7. 执行 SQL 语句时,应使用 SQLiteDatabase#insert()、update()、delete(), 不要使用 SQLiteDatabase#execSQL(),以免 SQL 注入风险。

  8. 如果 ContentProvider 管理的数据存储在 SQL 数据库中,应该避免将不受 信任的外部数据直接拼接在原始 SQL 语句中。

Bitmap、Drawable 与动画

  1. png 图片使用 TinyPNG 或者类似工具压缩处理,减少包体积。

  2. 使用完毕的图片,应该及时回收,释放宝贵的内存。

Bitmap bitmap = null;
loadBitmapAsync(new OnResult(result){
bitmap = result;
});
...使用该 bitmap...// 使用结束,在 2.3.3 及以下需要调用 recycle()函数,在 2.3.3 以上 GC 会自动管理,除非你明确不需要再用。
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
bitmap.recycle();}
bitmap = null;
  1. 在 Activity#onPause()或 Activity#onStop()回调中,关闭当前 activity 正在执行的的动画。

public void onPause() {
//页面退出,及时清理动画资源
mImageView.clearAnimation()
}
  1. 在动画或者其他异步任务结束时,应该考虑回调时刻的环境是否还支持业 务处理。例如 Activity 的onStop() 函数已经执行, 且在该函数中主动释放了资源, 此时回调中如果不做判断就会空指针崩溃。

  2. 使用 RGB_565 代替 RGB_888,在不怎么降低视觉效果的前提下,减少内 存占用。

  3. 大图片资源不要直接打包到 apk,可以考虑通过文件仓库远程下载,减小包 体积。

  4. 当 View Animation 执行结束时,调用View.clearAnimation()释放相关资源。

安全

  1. 将 android:allowbackup 属性必须设置为 false,阻止应用数据被导出。

  2. 如果使用自定义 HostnameVerifier 实现类,必须在 verify()方法中校验服务 器主机名的合法性,否则可能受到中间人攻击;如果使用自定义X509TrustManager 实现类,必须在 checkServerTrusted()方法中校验服务端证书的合法性,否则可能受到中间人攻击。

HostnameVerifier hnv = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
if("yourhostname".equals(hostname)){
return true;
} else {
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
return hv.verify(hostname, session);
}
}
};
  1. 在 SDK 支持的情况下,Android 应用必须使用 V2 签名,这将对 APK 文 件的修改做更多的保护。

  2. 所有的 Android 基本组件(Activity、Service、BroadcastReceiver、 ContentProvider 等)都不应在没有严格权限控制的情况下,将android:exported 设置为 true。

  3. WebView 应设置 WebView#getSettings()#setAllowFileAccess(false)、 WebView#getSettings()#setAllowFileAccessFromFileURLs(false) 、 WebView#getSettings()#setAllowUniversalAccessFromFileURLs(false),阻止 file scheme URL 的访问。

  4. 不要把敏感信息打印到 log 中。

  5. 确保应用发布版本的 android:debuggable 属性设置为 false。

  6. 本地加密秘钥不能硬编码在代码中,更不能使用 SharedPreferences 等本 地持久化机制存储。应选择 Android自身的秘钥库(KeyStore)机制或者其他安全 性更高的安全解决方案保存。

  7. addJavascriptInterface() 可以添加 JS 对本地 Java 方法的调用,但这本身 会导致恶意代码的攻击。在 Android 4.2(API Level 17)以下, 不应再使用这样的调用方式。在 Android 4.2 及以上, 需要对本地被远程调用的方法显式添加@JavascriptInterface annotation。

  8. 使用 Android 的 AES/DES/DESede 加密算法时,不要使用 ECB 加密模式, 应使用 CBC 或 CFB 加密模式; MD5 和 SHA-1、SHA-256 等常用算法是 Hash 算法,有一定的安全性,但不能代替加密算法。敏感信息的存储和传输,需要使用专业的加密机制。

加密模式有 ECB、CBC、CFB、OFB 等,其中 ECB 的安全性较弱,如果使用固
定的密钥,相同的明文将会生成相同的密文,容易受到字典攻击,建议使用 CBC、
CFB 或 OFB 等模式。
1) ECB:Electronic codebook,电子密码本模式
2) CBC:Cipher-block chaining,密码分组链接模式
3) CFB:Cipher feedback,密文反馈模式
4) OFB:Output feedback,输出反馈模式
  1. Android APP 在 HTTPS 通信中,验证策略需要改成严格模式。

  2. 在 Android 4.2(API Level 17)及以上,对安全性要求较高的应用可在 Activity中,对 Activity 所关联的 Window 应用 WindowManager.LayoutParams.FLAG_SECURE, 防止被截屏、录屏。但要注意的是,一个 Activity 关联的 Window 可能不止一个,如果使用了 Dialog / DialogFragment 等控件弹出对话框,它们本身也会创建一个新的 Window,也一样需要保护。

系统设计

  1. 不允许出现两段相同的逻辑块, 必须抽出为公共方法, 差异性使用参数控制, 避免修改时多处修改导致遗漏;

  2. 不允许出现两段相同的处于同一逻辑组的复杂布局, 必须抽为单独的include/merge;

  3. 不允许Activity内多Fragment之间的直接沟通, 必须通过Activity中转;

  4. 采用模块分类方式替代文件类别方式, 方便快速查找模块相关内容, 例: LoginActivity/LoginPreenter/LoginHttpRequest/LoginBean/LoginAdapter等所属同一登录模块的文件放入一个文件夹, 而不是所有activity放入一个文件夹, 所有adapter放入一个文件夹。

  5. 所有新定义的类/方法, 默认写成private, 只有在其他类需要引用时再看情况标为public, protected, package-private;

  6. java定义的父类中定义的方法如果子类重写会导致问题时, 添加final关键字;

其他

  1. 不能使用 System.out.println 打印 log。

  2. Log 的 tag 不能是" "。

  3. 项目建立REWADME.md文件,书写版本迭代中较重要的修改,包括需求修改,代码修改,三方库引用等;

参考资料

阿里巴巴 Android 开发手册

我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号接收我的最新文章

48c8b451e84f0c0216dc8626f3699eae.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值