本篇开始总结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. Ubuntu16.04+cuda8.0rc+opencv3.1.0+caffe+Theano+torch7搭建教程

    https://blog.csdn.net/jywowaa/article/details/52263711 学习中用到深度学习的框架,需要搭建caffe.theano和torch框架.经过一个月的不 ...

  2. intelliJ IDEA之使用svn或git管理代码

    intelliJ IDEA之使用svn管理代码 1.VCS—>import into Version Control—>Share Project(Subversion) 2.点击+    ...

  3. Tensorflow学习笔记03-使用神经网络做线性回归

    import tensorflow as tf import numpy as np #input就是输入数据,输入矩阵,in_size就是输入矩阵的列数(数据属性数量),out_size输出矩阵列数 ...

  4. 单元测试Mock框架Powermockito 【mockito1.X】

    <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...

  5. 阿里云Maven settings.xml文件

    <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Soft ...

  6. 20145212 罗天晨 MSF基础应用

    一.对exploit,payload,encode的理解 exploit是利用系统漏洞,相当于一个动态的过程. payload是攻击载荷,用于实现对漏洞的攻击,是实现漏洞攻击最核心的代码. encod ...

  7. 20145326蔡馨熤《网络对抗》——MSF基础应用

    20145326蔡馨熤<网络对抗>——MSF基础应用 实验后回答问题 用自己的话解释什么是exploit,payload,encode. exploit:起运输的作用,将数据传输到对方主机 ...

  8. python --- 07 补充( join 删除和添加 fromkeys ) 深浅拷贝

    一.基本数据类型补充 1.join() "*".join("马虎疼") # 马*虎*疼 把传递进去的参数进行迭代.  获取到的每个元素和前面的*进行拼接. 得到 ...

  9. 比酒量|2012年蓝桥杯B组题解析第三题-fishers

    (5')比酒量 有一群海盗(不多于20人),在船上比拼酒量.过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了.再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经 ...

  10. 4-Five-Youth

      ①People are always talking about 'the problem of youth'. If there is one--which I take leave to do ...