版权声明:本文出自汪磊的博客,转载请务必注明出处。

2月28日阿里巴巴首次公开内部安卓编码规范,试想那么多业务线,开发人员,没有一套规范管理起来是多么麻烦,以下是个人阅读Android基本组件部分过程中觉得不错的地方,摘录下来。

Android基本组件部分

1,Activity#onSaveInstanceState()方法不是Activity生命周期方法,也不保证一定会被调用。它是用来在Activity被意外销毁时保存UI状态的,只能用于保存临时性数据,例如UI控件的属性等,不能跟数据持久化存储混为一谈。持久化存储应该在Activity#onPause()/onStop()中实行。

2,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){ }
}
}

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

说明:

通过 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);

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

5,如非必须,避免使用嵌套的 Fragment。

说明:

嵌套 Fragment 是在 Android API 17 添加到 SDK 以及 Support 库中的功能,

Fragment 嵌套使用会有一些坑,容易出现 bug,比较常见的问题有如下几种:

1)onActivityResult()方法的处理错乱,内嵌的 Fragment 可能收不到该方法的回调,需要由宿主 Fragment 进行转发处理;

2)突变动画效果;

3)被继承的 setRetainInstance(),导致在 Fragment 重建时多次触发不必要的逻辑。

非必须的场景尽可能避免使用嵌套 Fragment,如需使用请注意上述问题。

正例:

 FragmentManager fragmentManager = getFragmentManager();
Fragment fragment =fragmentManager.findFragmentByTag(FragmentB.TAG);
if (null == fragment) {
FragmentB fragmentB = new FragmentB(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();   fragmentTransaction.add(R.id.fragment_container, fragmentB, FragmentB.TAG).commit(); }

反例:

 Fragment videoFragment = new VideoPlayerFragment();

 FragmentTransaction transaction = currentFragment.getChildFragmentManager().beginTransaction();

 transaction.add(R.id.video_fragment, videoFragment).commit();

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

说明:

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

7,当前 Activity 的 onPause 方法执行结束后才会执行下一个 Activity 的 onCreate 方法,所以在 onPause 方法中不适合做耗时较长的工作,这会影响到页面之间的跳转效率。

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

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

正例:

     @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder myViews; if (convertView == null) { myViews = new ViewHolder(); convertView = mInflater.inflate(R.layout.list_item, null); myViews.mUsername = (TextView) convertView
.findViewById(R.id.username);
convertView.setTag(myViews);
} else { myViews = (ViewHolder) convertView.getTag(); } Info p = infoList.get(position); String dn = p.getDisplayName; myViews.mUsername.setText(StringUtils.isEmpty(dn) ? "" : dn);
return convertView; } static class ViewHolder { private TextView mUsername; }

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

说明:

如果 registerReceiver()和 unregisterReceiver()不成对出现,则可能导致已经注册的

receiver 没有在合适的时机注销,导致内存泄漏,占用内存空间,加重 SystemService 负担。

部分华为的机型会对 receiver 进行资源管控,单个应用注册过多 receiver 会触发管控模块抛出异常,应用直接崩溃。

正例:

 public class MainActivity extends AppCompatActivity {

         private static MyReceiver myReceiver = new MyReceiver();

         @Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("com.example.myservice");
registerReceiver(myReceiver, filter);
} @Override
protected void onPause() {
super.onPause();
unregisterReceiver(myReceiver);
}
}

反例:

 public class MainActivity extends AppCompatActivity {

         private static MyReceiver myReceiver; 

         @Override
protected void onResume() {
super.onResume();
myReceiver = new MyReceiver();
IntentFilter filter = new IntentFilter("com.example.myservice");
registerReceiver(myReceiver, filter);
} @Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}

Activity 的生命周期不对应,可能出现多次 onResume 造成 receiver 注册多个,但最终只注销一个,其余 receiver 产生内存泄漏。

以上就是阿里巴巴安卓编码规范中Android基本组件部分提及的一些规范,并没有全部列出来,只是记录一些个人觉得不错的地方,整体下来感觉都是细微的地方,感兴趣的同学可以自行查找完整版《阿里巴巴Android编码规范》阅读一下,里面还是有点干货的。

好了,本篇到此结束,希望对你有用。

《阿里巴巴Android编码规范》阅读纪要(一)的更多相关文章

  1. 《阿里巴巴Android编码规范》阅读纪要(二)

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 本篇继续上一篇<阿里巴巴Android编码规范>阅读纪要(一) ,还是建议各位同学有时间完整阅读一下<阿里巴巴Android编码规 ...

  2. 最全面的 Android 编码规范指南

    最全面的 Android 编码规范指南 本文word文档下载地址:http://pan.baidu.com/s/1bXT75O 1. 前言 这份文档参考了 Google Java 编程风格规范和 Go ...

  3. 【转】Android编码规范建议18条

    转自:http://www.chinaz.com/design/2015/0908/443732.shtml Android编码规范建议18条 适合手机app设计师和android 工程师阅读. 1. ...

  4. 浅谈Android编码规范及命名规范

    前言: 目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑. 现大框架已经完成,正在进行细节模块上的开发 抽空总结一下Android项目的开发规范:1.编码规范 ...

  5. 最详细最权威的Android 编码规范

    1. 前言 这份文档参考了 Google Java 编程风格规范和 Google 官方 Android 编码风格规范.该文档仅供参考,只要形成一个统一的风格,见量知其意就可. 1.1 术语说明 在本文 ...

  6. 阿里巴巴Java编码规范插件安装使用指南

    编码规范插件安装使用指南 阿里技术公众号公布的<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,后又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来. 为了让开发 ...

  7. Android编码规范01

    目标: 掌握Java & Android命名规范 在研究Android源代码的基础上改进命名规范 考核内容 说出四种常用的命名法 比较java和C#的命名规范的不同点 总结: 读不同程序员写的 ...

  8. 【Android学习】Android编码规范

    四种常见的命名法 比较Java和c#的命名规范的不同点 常量用大写 java方法首字母不大写,应该小写 函数行数限制 不要用拼音 参照物,Android源码 看源码工具,SourceInsight 和 ...

  9. Android编码规范05

    编码逻辑规范总结: 1.避免使用多个类放在一个文件里,除非是一次性使用的内部类 2.一个方法代码长度最好不要超过35行 3.原则上尽量不要修改自动生成的文件,如R文件 4.Final String 取 ...

随机推荐

  1. Mysql(三)-2:数据类型

    一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考: http://www.runoob.com/mysql/mysql-data ...

  2. java对excel表格上传和下载的处理方法

    详见:http://www.jb51.net/article/120443.htm

  3. JS Cookie丢失问题

    JS Cookie丢失问题 前些天有人问我vue中使用proxy发送请求,为什么请求时cookie丢失,首先说一下我对cookie的理解: 1.cookie在正常情况下是会在每次请求时自动携带, 2. ...

  4. UVALive - 4329 Ping pong 树状数组

    这题不是一眼题,值得做. 思路: 假设第个选手作为裁判,定义表示在裁判左边的中的能力值小于他的人数,表示裁判右边的中的能力值小于他的人数,那么可以组织场比赛. 那么现在考虑如何求得和数组.根据的定义知 ...

  5. POJ - 1190 生日蛋糕 dfs+剪枝

    思路:说一下最重要的剪枝,如果当前已经使用了v的体积,为了让剩下的表面积最小,最好的办法就是让R尽量大,因为V = πR 2H,A' = 2πRH,A' = V / R * 2 ,最大的R一定是取当前 ...

  6. HDU - 2147 kiki's game 巴什博弈

    思路:以终点(n, m)作为P态,倒推各个坐标的状态,最终得到结论:行数或列数是偶数就能赢,否则输.        AC代码 #include <cstdio> #include < ...

  7. 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码

    一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...

  8. Android WebView 保持登录问题

    最近有个需求是这样的:在应用中添加一个商城,商城的实现是H5(包括登录).需要将这个H5嵌到原生应用中,并在原生代码中添加支付功能. 接到这个需求的时候,想这不是很简单么,用WebView加载这个页面 ...

  9. Redis笔记1-redis的搭建和使用

    1.   Redis的安装 1.1. Redis的安装 Redis是c语言开发的. 安装redis需要c语言的编译环境.如果没有gcc需要在线安装.yum install gcc-c++ 安装步骤: ...

  10. Oracle trunc() 函数处理数字、日期的整理

    --Oracle trunc()函数的用法/**************日期********************/1.select trunc(sysdate) from dual --2013- ...