早上5点自然醒,写下第一篇总结,引来很多人的关注,一些人跟我要github上的源码,非常的抱歉啊,虽然公司解散了,但那些资产还是需要保密的,于情于理都不能公开给大家;不过附上我的Github帐号 https://github.com/SwordBearer,互粉吧
;) ,在接手这款即时通讯开发后,个人还是学到了很多东西,欢迎一起来交流交流。
现在从开发层面说说自己遇到的事吧,3月份接手这个项目,还有另外一位同事(比我早毕业一年),我们两个人一起开发。如果叫我一句话介绍当时对这项目的感觉,那只有三个字:一坨屎。 Android项目初期就是几个新手在做,从一开始就没有个好底子,随后又经手了四五拨人,往上不断堆积,给整个项目积攒了无数问题:
1.这几拨人最大的共同点就是:几乎不写注释!,代码干干净净!不多一行也不少一行!
2.命名不规范,甚至Socket接口和包名,类名都不对应,连英文都有拼错的,所有Fragment都写成Flagment,这样一两处倒还好,关键是太多了。
以上两个问题随之带来的结果就是出了BUG后,只能连猜带读去解决;可我觉得这都是一个程序猿最基本的常识啊,写规范注释,规范命名;
3.对于第三方库的引用问题,以前的代码中,凡是用到第三方库,尤其是UI的,基本上是把整个项目代码都copy进主项目,顺带把一些文件前面的注释都去了,并不是通过库引用方式来使用,所以谁加进来的UI控件,别人基本上不知道怎么用,因为没有文档。连最核心的WebSocket网络连接代码,也是从Github上扒下来,然后塞进去,不加注释,这就造成另外一个极其严重的问题,下文再述;
细细想想,这半年基本上都是在替人擦屁股,不过在重构整个项目的过程中,还是学到了很多的东西,尤其是在性能和Socket连接上,收获颇多;
Android性能存在很多问题,内存占用大,点击响应慢,数据库读写慢,UI绘制慢等等,接下来一一分析一下;
项目中有用到一个标题栏,所有页面中都会出现,原来项目中,是定义了一个无比复杂的自定义控件,有左侧返回按钮,右侧点击按钮,中间标题,以及进度条等等,所有页面用这一个控件,由于使用了这个标题栏,所有Activity的XML布局中就多了一层。这个标题栏内部又嵌套好几层,而大多标题栏只有左侧返回按钮和中间标题栏,剩余的那些控件就隐藏起来,这样够凶残吧,过度封装害死人。如何改进?我想大家都知道——ActionBar,移除原来所有的自定义标题栏,布局中减少了层次,并且ActionBar扩展性更高,可以显示更多的操作,我没有测试这个改进会有多少ms的提升,但是一定会更快。
好多ListAdapter没有使用复用原理!
有两个问题着重说一下,一个是数据库优化,另外一个是Socket连接问题;
一,数据库优化
app中有一个场景是更新一系列联系人,测试数据是780条(还包括112个分组,分组下的联系人总共有780条),当数据变化后,需要将原来的联系人删除,先保存分组到分组表,再将这780条插入联系人表。当时就在这一块总是出现数据丢失的情况,一部分联系人没有保存,这是一个很严重的问题。问题就出在SQLite连续插入的地方,原代码是如何插入的呢?数据库打开,遍历插入,然后关闭,最原始最简单的方法,可是测试了一下,光780条数据,用时20s,很恐怖的结果,20s,一段广告都看完了。
所以这就演变成了一个很常见的问题:如何在SQLite中一次性插入大量数据?
方法1,开启事务,这是必须要做的,在for循环外开启事务,循环中插入数据,循环结束关闭事务。这样写了之后,20s立马变成了4s,当时就震精了。原因:事务是在内存中进行处理,当所有插入完成后,再一次性写入数据库,每一次写入都是一次 IO操作,SQLite是个性能很低的数据库,听闻比文件操作的速度慢10倍左右(没有具体进行比较过)。
方法2,使用SqliteStatement,使用后效果杠杠的,至于为什么,可以参考这里 http://liuzhichao.com/p/1664.html ;
讲方法1和方法2结合使用后(最外层开启事务,然后使用SqliteStatement操作,最后关闭事务),效果如何呢? 20s直接降到 1s 左右!而且1s 完全可以接受了;
二,Socket连接问题
做过即时通讯的人都知道(当然我还是门外汉),客户端需要一直保持一个socket长连接,并且要一直发送心跳来维护这个长连接,如果中断了,需要重新请求连接。
我们的socket连接是放在一个单独的thread里面去实现数据请求和接收的,这个设计本身其实是有问题的。首先,Android这种平台,对内存占用非常敏感,后台的线程一不留神就会被系统kill掉,这就是我们为什么一直断网的最终原因;其次,socket长连接算是这个应用中最低层,最核心的部分,所有的数据接收发送最终都是在这里处理,不应该将它仅仅用一个线程来处理,不然在通讯过程中,遇到诸如锁屏,网络中断,后台运行等都有问题,当初在重构的时候是把它放在了一个Service里面,然后对socket在进行定时心跳维护等等,此处涉及的比较多,就不展开了。
经历这个项目之后,我就在想,如何才能构建一个高性能的Android架构呢?看过INFOQ上分享的微信开发过程 点击打开链接 ,着实让人膜拜,一个庞大的系统,也是一点点积累起来的,技术,就是这么纯粹,只需要时间和耐心去打磨而已。
说多了都是泪,公司倒了,项目停了,心里却留下了一大段空白,有对技术的,也有对创业的,以后慢慢再叙述吧.........