本篇开始总结Android开发中的一些注意事项,提高代码质量(仅供参考):

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

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) {
if (Config.LOGD) {
Log.d(LOGTAG, "activity not found for " + mimeType + " over " + Uri.parse(url).
getScheme(), e);
}
}
}
}

3.  避免在 Service#onStartCommand()/onBind()方法中执行耗时操作,如果确实有需求,应改用 IntentService 或 采用其他异步机制完成;避免在BroadcastReceiver#onReceive()中执行耗时操作,如果有耗时操作,应该创建IntentService完成,而不应该在BroadcastReceiver内创建子线程去做。查看IntentService的具体使用教程(后补)

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

5.  对于只用于应用内的广播,优先使用 LocalBroadcastManager 来进行注册和发送,LocalBroadcastManager 安全性更好,可以避免广播泄露以及广播被拦截等安全问题,同时相对全局广播,本地广播的更高效

LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
}

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

7.  Activity 或者 Fragment 中动态注册 BroadcastReceiver 时, registerReceiver()和unregisterReceiver()要成对出现。否则会导致内存泄露,加重 SystemService 负担。

8.  在需要时刻刷新某一区域的组件时,建议通过以下方式避免引发全局 layout 刷新:

  1) 设置固定的 view 大小的高宽,如倒计时组件

  2) 调用 view 的 layout 方式修改位置,如弹幕组件等;

  3) 通过修改 canvas 位置并且调用 invalidate(int l, int t, int r, int b)等方式限定刷新区域;

  4) 通过设置一个是否允许 requestLayout 的变量,然后重写控件的 requestlayout、onSizeChanged 方法,判断控件的大小没有改变的情况下,当进入requestLayout 的时候,直接返回而不调用
    super 的 requestLayout 方法。
 
9.  新建线程时,必须通过线程池提供(AsyncTask 或者 ThreadPoolExecutor或者其他形式自定义的线程池),不允许在应用中自行显式创建线程。线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。说明:Executors 返回的线程池对象的弊端如下:

  1) FixedThreadPool 和 SingleThreadPool : 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM;
  2) CachedThreadPool 和 ScheduledThreadPool : 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
int KEEP_ALIVE_TIME = 1;
TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue, new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());

11.  谨慎使用 Android 的多进程,多进程虽然能够降低主进程的内存压力,但会遇到如下问题:
  1) 不能实现完全退出所有 Activity 的功能;
  2) 首次进入新启动进程的页面时会有延时的现象(有可能黑屏、白屏几秒,是白屏还是黑屏和新 Activity 的主题有关);
  3) 应用内多进程时,Application 实例化多次,需要考虑各个模块是否都需要在所有进程中初始化;
  4) 多进程间通过 SharedPreferences 共享数据时不稳定。

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

// 使用结束,在 2.3.3 及以下需要调用 recycle()函数,在 2.3.3 以上 GC 会自动管理,除非你明确不需要再用。if (Build.VERSION.SDK_INT <= 10) {
  bitmap.recycle();
}
bitmap = null;

13.  在 Activity.onPause() 或 Activity.onStop() 回调中,关闭当前 activity 正在执行的动画。

public void onPause(){
//页面退出,及时清理动画资源
mImageView.clearAnimation();
}

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

android.graphics.Bitmap.Config 类中关于图片颜色的存储方式定义:
   1) ALPHA_8 代表 8 位 Alpha 位图;
   2) ARGB_4444 代表 16 位 ARGB 位图;
   3) ARGB_8888 代表 32 位 ARGB 位图;
   4) RGB_565 代表 8 位 RGB 位图。
位图位数越高,存储的颜色信息越多,图像也就越逼真。大多数场景使用的是ARGB_8888 和 RGB_565,RGB_565 能够在保证图片质量的情况下大大减少内存的开销,是解决 oom 的一种方法。但是一定要注意 RGB_565 是没有透明度的,如果图片本身需要保留透明度,那么就不能使用 RGB_565。

Config config = drawableSave.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888 : Config.RGB_565;
Bitmap bitmap = Bitmap.createBitmap(w, h, config);

15. ※ ※ ※  在有强依赖 onAnimationEnd 回调的交互时,如动画播放完毕才能操作页面 , onAnimationEnd 可能会 因各种异常没被回调 (参考:https://stackoverflow.com/questions/5474923/onanimationend-is-not-getting-called-onanimationstart-works-fine),建议加上超时保护 或通过 postDelay 替 代 onAnimationEnd。

View v = findViewById(R.id.xxxViewID);
final FadeUpAnimation anim = new FadeUpAnimation(v);
anim.setInterpolator(new AccelerateInterpolator());
anim.setDuration(1000);
anim.setFillAfter(true);
new Handler().postDelayed(new Runnable() {
public void run() {
if (v != null) {
v.clearAnimation(); // 当 View Animation 执行结束时,调用 View.clearAnimation()释放相关资源
}
}
}, anim.getDuration());
v.startAnimation();

Android开发代码规范总结的更多相关文章

  1. Android开发代码规范(转)

    Android开发代码规范 1.命名基本原则    在面向对象编程中,对于类,对象,方法,变量等方面的命名是非常有技巧的.比如,大小写的区分,使用不同字母开头等等.但究其本,追其源,在为一个资源其名称 ...

  2. Android开发代码规范

    目录 1.命名基本原则  2.命名基本规范 2.1编程基本命名规范 2.2分类命名规范 3.分类命名规范 3.1基本数据类型命名规范 3.2控件命名规范 3.3变量命名规范 3.4整个项目的目录规范化 ...

  3. 黑客破译android开发代码真就那么简单?

    很多程序员辛辛苦苦开发出的android开发代码,很容易就被黑客翻译了. Google似乎也发现了这个问题,从SDK2.3开始我们可以看到在android-sdk-windows\tools\下面多了 ...

  4. Android开发编码规范(自用)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持!   Android开发编码规范 目的及指导原则 目的 统一规范 Eclipse编辑环境 ...

  5. android 开发代码被黑客破译有那么容易吗?

    很多程序员辛辛苦苦开发出的android开发代码,很容易就被黑客翻译了. Google似乎也发现了这个问题,从SDK2.3开始我们可以看到在android-sdk-windows\tools\下面多了 ...

  6. ym——Android开发编码规范(自用)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android开发编码规范 目的及指导原则 目的 统一规范 Eclipse编辑环境下J ...

  7. 你不可不看的Android开发命名规范

    标识符命名法最要有四种: Camel(骆驼)命名法:除首单词外,其余所有单词的第一个字母大写,如:fooBar; Pascal命名法:所有单词的第一个字母大写,如:FooBar: 下划线命名法:单词与 ...

  8. Android开发 --代码布局

    Android开发 --代码布局 在线性布局LinearLayout里加入view比较简单,因为属性比较少,布局简单 示例,加入一个TextView LinearLayout layout = (Li ...

  9. web前端开发 代码规范 及注意事项

    web前端开发 代码规范 及注意事项 外部命名规范 html .js .css文件名称命名规范 my_script.js my_camel_case_name.css my_index.html 路径 ...

随机推荐

  1. 在html中引入css、js和jQuery的方法

    在html中引入css代码 在html中插入CSS样式表的方法有三种: 1.外部样式表(External style sheet):即所有的样式单独写在一个.css文件中,在html文件的head部分 ...

  2. VMware Workstation Pro14安装

    1. 下载VMware Workstation Pro14,注意,这个链接支持win7 64及以上系统 2.  点击进入安装 3. 接受许可协议 4. 选择安装目录,是否选择增强型键盘驱动程序 5. ...

  3. gdb调试问题汇总

    1. 宏调试 在GDB下,我们无法print宏定义,因为宏是预编译的.但是我们还是有办法来调试宏,这个需要GCC的配合. 在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了.另外,你 ...

  4. ORA-00600: internal error code, arguments: [13030], [20]一例解决

    两年没有接触oracle了,中午,一环境update from的时候出现ORA-00600: internal error code, arguments: [13030], [20]异常,经查,官网 ...

  5. UI自动化(二)css选择器

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. bzoj 3325 密码 - Manacher

    题目传送门 需要root权限的传送点 题目大意 已知一个串,以每个字符为中心的最长回文串长,以及每两个字符中间为中心的最长回文串长.求字典序最小的这样一个串.题目保证有解. 考虑Manacher的过程 ...

  7. bzoj 4591 超能粒子炮·改 - Lucas

    Description 曾经发明了脑洞治疗仪&超能粒子炮的发明家SHTSC又公开了他的新发明:超能粒子炮·改--一种可以发射威力更加 强大的粒子流的神秘装置.超能粒子炮·改相比超能粒子炮,在威 ...

  8. Received empty response from Zabbix Agent at [172.16.1.7]...

    Centos7.5  zabbix添加主机发现ZBX爆红报错 原因:在配置/etc/zabbix/zabbix_agentd.conf中172.16.1.71写成了127.16.1.71 解决方法:重 ...

  9. Python 必备好库 - 好工具收藏

    apscheduler collections collections.OrderDict collections.defaultdict Python 标准库提供了 collections 模块.这 ...

  10. centos6配置网络常见问题

    1. 启用网卡 查看网卡模块: lsmod 移除网卡:modprobe -r e1000 装载网卡: modprobe e1000 2. 配置网络 vim /etc/sysconfig/network ...