昨天项目组,进行了一波线上代码的codereview的分享,把线上有改进优化的代码的问题拿出来分享。是一次有预谋、有计划、有组织的好分享。所以这里也记录,防止后面出现犯同样的错误吧。
cursor未关闭
这种问题我以为只有面试中才会有,没想到可能一不小心就会发生在身边。一定要记得关闭游标cursor.close()。
popwindow和dialog的show和dissmiss一定要判断activity是否存活
如果不判断直接使用的话,可能会导致crash,View not attached to window manager。可以在dismiss之前判断Activity不为null
UI线程不能处理耗时任务
这一点都知道,但是如果封装多了,你可能不是特别确定这个线程是ui线程还是非ui线程,所
以每当写耗时任务的时候都自己注意下当前线程
BroadcastReceiver不能新建线程做耗时任务,更不能直接做耗时任务
新建线程做耗时任务这一点是自己都没有想到的,BroadcastReceiver中onReciver方法时
间不能超过10s,否则就会anr,所以不能直接做耗时任务,而如果新建线程做耗时任务的话,
这样子如果onReceiver的进程被干掉了,也就是onReciver走完了,那么宿主进程干了,宿
主上所有的线程会被回收掉,所以耗时任务也会做不了。这里建议如果有耗时任务使用
service。
BroadcastReceiver中的Context使用要注意
广播中的context有些方法是没有实现,所以最好是使用application的context
Handler不应该是activity的非静态匿名内部类
这种做法以前很多时候会这么干,当时也就没有多想,今天回头看了下这里是会存在内存泄漏的
风险。一般Handler在类中以匿名内部类的形式出现,隐式持有外部activity的引用,但是
handler的又被Message对象持有(msg.target的对象默认是当前的handler),如果
activity的生命周期结束,但是message还在队列中,可能导致activity不能被回收导致
内存泄漏。所以一般都使用静态内部类的加载方式,原因是静态内部类不会持有对外的引用。
常用的Fragment建议使用show和hide,而不是频繁的new
页面频繁的新建,页面的一些业务app可能整个生命周期只需要一次,这样频繁的新建回收会导
致垃圾产生的量多,gc回收的频率也会增加,这样回收的时间也会加长,还会增加cpu和电量的
损耗。
StringBuffer中append字符串需要判空
常常使用StringBuffer的append的方法时候不会添加判空,一旦成串发给后台可能就是产生
问题。而且最好不要使用append("name"+"&")类似这种的,+的效率并没有直接append的
效率高。
慎用try catch
很多时候为了保证代码块的健壮性,添加try catch 过多的trycatch会增加程序的负担,特
别是多个逻辑放在一个try中,一旦第一个发生异常,后面的都将获取不到,所以一个try最好
只放一个逻辑,只对一个变量try,这样第一个发生出错其他的数据逻辑还能有,比如推送中,
后台可能需要用户的token,还需要设备的id,还有设备的sim卡的信息,如果sim卡信息没
有,其他两个能获取到也能推送,如果写在一个try中,第一个逻辑就是获取sim卡信息的,一
旦出错,所有的都获取不到,这样推送也进行不了了。
类单一职责的问题
一个类承担一个职责,不要很多乱七八糟逻辑都在一个里面,比如一个类处理播放的逻辑,你就
不应该把下载的逻辑也放在这个里面,这样会导致这个类臃肿,这么多逻辑的高耦合,不符合高
内聚,低耦合的设计思想。还有类中的方法也应该单一方法处理单一逻辑这样才能提高方法的复
用性,也能提高阅读代码的质量。
接口定义回调的方法需要三思
回调方法的个数和意义都要想清楚了再定义,要从全局考虑。不然后面修改起来可能会影响很多逻辑,到时候再修改就会很麻烦。
资源字符串不要hardcode在代码里面
不要为了偷懒直接将字符串写在代码中,如果程序需要多语言适配,那么再改起来会很头大。而且这也不符合规范。
方法参数控制
如果一个方法的参数超过4个就可以考虑用类来封装,然后把参数传递改为直接传类的引用
不要再for中做remove作,会漏删
for中每次remove操作都会调用一次arrayCopy的操作,会导致一些元素的索引值变
化,但是for循环的int的标志会递增,就可能导致漏删。建议使用foreach或迭代器操作。
感兴趣可以看一下arraylist中的remove方法。