ANDROID 开发规范总结

来源:互联网 发布:许嵩和方文山歌词知乎 编辑:程序博客网 时间:2024/05/18 02:21

ANDROID 开发规范总结

 

基本原则

工欲善其事,必先利其器

充分利用好工具,让电脑代替人脑

 

最高境界是不写任何代码

和产品人员充分讨论,仔细评估待实现的功能,明确方案,不做无用功(最好能把需求砍掉J)

 

为质量负责

 提交代码前仔细检查,找同事帮忙review

 如果迫不得已,挖坑前做好标记(TODO)

 

工具和开发环境

开发推荐使用eclipse,或者类eclipse环境

配置好Android Formatter

配置好Save Actions

Formatter配置

Eclipse -> Window -> Preferences

 

 Import 导入相应的formatter.xml文件

 


Save Actions配置

eclipse -> Window -> Preferences

 

配置成如上的形式就可以了。


UI编码规范

不要阻塞UI线程

1、UI线程内不能做耗时操作,如文件读写、数据库操作、逻辑运算等,建议每次调用耗时不超过10ms,如果超过,建议在工作线程内完成。

2、使用trace view查找耗时方法。

3、使用StrictMode监测耗时操作。

优化高频率运行的代码

1、不频繁进行findViewById、getString…等查找资源的操作, 应使用临时对象缓存。

2、避免频繁创建对象

     –自定义View不能每帧刷新都去创建新的Paint、Rect、Matrix等对象,应使用临时对象缓存,一次性创建并初始化,每次直接使用。

     –当需要重复使用Bitmap时,不要频繁进行decode,而应将其缓存在cache中。(注:安卓3.0以下可使用软引用cache,3.0以上使用LRU cache并需自己做好内存控制。 为了统一和适配,建议使用后者”)。

避免过度刷新

主要是item很多的ListView的过度刷新

1、  不要频繁调用Adapter的notifyDataSetChanged方法,只更新需要被更新的行。

常见的场景:后台频繁更新数据,界面接收到回调后直接notifyDataSetChanged。正确的方法:判断后台数据对应的行是否可见,然后刷新该View。

2、listview滑动的过程中少调用notifyDataSetChanged。

3、Adapter需使用复用机制,不能每次getView都去重新inflate, 应尽量利用convertView 和 ViewHolder来实现复用机制。

布局扁平化

1、  多使用merge、ViewStub标签。

2、使用RelativeLayout代替多级Linearlayout。

3、使用hierarchy view排查布局问题。

不使用大尺寸图片

1、使用BitmapFactory类的decode函数生成bitmap时,调整采样间隔和缩放尺寸,进行预缩放处理

2、避免使用多套分辨率图片

为了保证不同分辨率手机ui效果,可能会在hdpi、xhdpi等目录下各保持一份图片,这样做会增加apk体积,尽量只放一套图片,然后指定View的高宽,在不同分辨率下定义不同的dimen。

正确使用inflate方法

不正确的使用inflate(Contextcontext, int resource, ViewGroup root)方法导致View Hierarchy多嵌套了一层,会导致View效率低下。

错误的作法:

正确的做法:

解决办法:在inflate第三个参数给定root的时候,应该在xml文件中用merge标签消除嵌套,并且在代码中设置相关属性(xml文件中使用merge标签,对这一标签的任何属性都将失效,包括id,可以看作没有这一层)。

使用ColorFilter节省图片资源

一个按钮拥有多种状态,为满足这些状态使用了不同的切图

尽可能的使用ColorFilter,使用ColorFilter可节省50%内存使用

界面元素尽量少且简单

如果一个Activity展示的元素过多,肯定会影响性能,可以考虑下面的方法:

1、把业务逻辑分拆到不同的界面。

2、使用Fragment展示不同的界面。

3、使用自定义Layout展示不同的界面,不同的情况切换不同的Layout。

UI逻辑和业务逻辑分离

如果activity逻辑很复杂,建议将UI和业务逻辑放到单独的类实现,用Message传递消息,

Adapter数据变化问题

如果在非ui线程修改Adapter内容(增加item),会抛出下面的异常:

java.lang.IllegalStateException: Thecontent of the adapter has changed but ListView did not receive a notification.Make sure the content of your adapter is not modified from a background thread,but only from the UI thread

修改方法是在UI线程中修改,可以通过Handler解决数据传递问题。

使用include复用layout

Include可以减少重复资源,布局文件更清晰。

设置窗口背景为null

<item name="android:windowBackground">@null</item>

可以省去window背景的绘制,提高界面效率

 

实践经验

修复BUG时,避免简单粗暴

修复BUG时,要尽量找到问题的根本原因。不要直接加上try/catch完事。

 

避免Context对象使用强制类型转换

避免使用Context转换为Activity,禁止使用Context转换为Application。

持有Context对象

尽量用context.getApplicationContext代替

 

谁申请谁释放原则

Receiver的注册和注销,包括Android的和LocalBroadcastManager

Service的bind和unbind

一定要保证成对出现,否则导致内存泄漏

Fragment的细节

Fragment的onCreateView/onDestroy/handleMessage,要判断Activity是否为空,是否finish

 

Fragment继承注意事项

继承Fragment的子类,其构造函数必须是无参数的,需要的Activity父对象可以通过onAttach(Activity)来传递。

 

public Activity mContext;

 

   @Override

   public void onAttach(Activity activity) {

       super.onAttach(activity);

       this.mContext = activity;

}

 

否则会报告如下错误:

 

Caused by:android.support.v4.app.Fragment$InstantiationException: Unable to instantiatefragment alj: make sure class name exists, is public, and has an emptyconstructor that is public

        at android.support.v4.app.Fragment.instantiate(Fragment.java:395)   com.qihoo360.mobilesafe.ui.fragment.settings.SettingsView -> alj

        at android.support.v4.app.FragmentState.instantiate(Fragment.java:96)

        atandroid.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1726)

        at android.suppo

 

Dialog的show/dismiss

需要判断Activity是否finish

 

AsyncTask的onPost

需要判断Activity是否finish

 

Android的Receiver上下文

Android的Receiver上下文是限制上下文,不能用其Context去bindService操作

 

Handler/Runnable内存泄漏

要小心Handler/Runnable对Activity等的长期持有

 

AsyncTask内存泄漏

要小心AsyncTask对Activity等的长期持有

 

Toast使用

Toast最好在UI线程中启动,否则可能会报错:

 

04-17 19:04:29.424: E/CrashHandler(11689):Crash Log BEGIN

04-17 19:04:29.424: E/CrashHandler(11689):java.lang.RuntimeException: Can't create handler inside thread that has notcalled Looper.prepare()

04-17 19:04:29.424: E/CrashHandler(11689):at android.os.Handler.<init>(Handler.java:121)

04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast$TN.<init>(Toast.java:317)

04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast.<init>(Toast.java:91)

 

明文字符串

尽量不要在传输中直接传输明文字符串。

0 0
原创粉丝点击