工欲善其事,必先利其器
充分利用好工具,让电脑代替人脑
最高境界是不写任何代码
和产品人员充分讨论,仔细评估待实现的功能,明确方案,不做无用功(最好能把需求砍掉J)
为质量负责
提交代码前仔细检查,找同事帮忙review
如果迫不得已,挖坑前做好标记(TODO)
开发推荐使用eclipse,或者类eclipse环境
配置好Android Formatter
配置好Save Actions
Eclipse -> Window -> Preferences
Import 导入相应的formatter.xml文件
eclipse -> Window -> Preferences
配置成如上的形式就可以了。
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(Contextcontext, int resource, ViewGroup root)方法导致View Hierarchy多嵌套了一层,会导致View效率低下。
错误的作法:
正确的做法:
解决办法:在inflate第三个参数给定root的时候,应该在xml文件中用merge标签消除嵌套,并且在代码中设置相关属性(xml文件中使用merge标签,对这一标签的任何属性都将失效,包括id,可以看作没有这一层)。
一个按钮拥有多种状态,为满足这些状态使用了不同的切图
尽可能的使用ColorFilter,使用ColorFilter可节省50%内存使用
如果一个Activity展示的元素过多,肯定会影响性能,可以考虑下面的方法:
1、把业务逻辑分拆到不同的界面。
2、使用Fragment展示不同的界面。
3、使用自定义Layout展示不同的界面,不同的情况切换不同的Layout。
如果activity逻辑很复杂,建议将UI和业务逻辑放到单独的类实现,用Message传递消息,
如果在非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可以减少重复资源,布局文件更清晰。
可以省去window背景的绘制,提高界面效率
修复BUG时,要尽量找到问题的根本原因。不要直接加上try/catch完事。
避免使用Context转换为Activity,禁止使用Context转换为Application。
尽量用context.getApplicationContext代替
Receiver的注册和注销,包括Android的和LocalBroadcastManager
Service的bind和unbind
一定要保证成对出现,否则导致内存泄漏
Fragment的onCreateView/onDestroy/handleMessage,要判断Activity是否为空,是否finish
继承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
需要判断Activity是否finish
需要判断Activity是否finish
Android的Receiver上下文是限制上下文,不能用其Context去bindService操作
要小心Handler/Runnable对Activity等的长期持有
要小心AsyncTask对Activity等的长期持有
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.
04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast$TN.
04-17 19:04:29.424: E/CrashHandler(11689):at android.widget.Toast.
尽量不要在传输中直接传输明文字符串。