关于移动平台工程的一些心得
2012-08-29 00:34
281 查看
做Android也有一年多了,因为在小公司么,项目经历了无数,精品确实是不太多...不过好歹是自已做过了一些东西,而且最近的IM项目,让我去搭架构了,目前看来稳定性有一些欠佳,但是至少我是没有太失望的,我觉得这个时间,这个进度也还行了,即使这是个外包项目,我拒绝为了做得特别快而极混而不想,再说,不想不去一直修改重构的话,怎么可能稳定呢?
但是也是有一些东西值得思考的,已经做了很多项目了,应该有一些显示的经验或教训了,应该不至于像以前一样拿起来后,也没有太多的顾忌,直接就想架构后就直接开写了,今天下午在一次次RemoteService ANR 的苦闷中,我萌生了写这篇博客的念头。
还是先从今天引起反思的起因事件写吧,起因是为啥呢?RemoteService ANR了,那ANR是为什么呢? 很简单XMPP的网络请求数据,数据的写入数据库我都没有放入线程中写。那为什么我当年在构造这些函数时没有用线程+异步,也一年经验了怎么会犯这错误呢? 那回忆一下吧,其实在开始构造Remote Service时,我确实是想到了异步,但是当时并没有用,一是因为觉得可能没有这么严重吧(那时离作××APP的帐户系统时已经有些久远了,已经忘记了当时异步的极端重要性),二是对Remote Service的秉性不太熟悉,觉得一个后台进程,不开线程自已也是一个线程啊,相对我Activtiy完全是异步么..,当然现在明白这是完全完全错误的想法..Remote
Service 是Service 是组件,而不是线程,必然不是想像中那样用的。
---------
那于是今天先反思一下××APP帐户系统当时的架构,当时是单例的AccountSys作为了中枢系统,UI这端比如是一个Activity注册了AccountSys的回调接口之后,直接调用AccountSys的函数,而这个函数在另一个线程中从网络下载完后,就会处理存储更改数据库这类事情,处理数据库的类叫DBHelper,AccountSys也注册了DBHelper的一个回调接口,在线程中作完网络下载之后,其会调用DBHelper的函数进行数据库操作,但是这个操作也是异步的,操作后AccountSys会响应了DBHelper的回调接口。(这时说明DBHelper的数据库操作已经做完了,并告知了AccountSys了),这时AccountSys再执行其相对于Activity(即UI)的回调函数,这样UI便得到了最终网络和数据库操作完成了结果。
大体还记得那时出现了一些什么样的Bug,首先,因为AccountSys是单例的,同时只能一个AccountSys作为其回调对象,怕时有几个功能几乎很近发生时,会有回调被挤掉而不能完成。这种可能性理论上绝对是存在的,就算是一个Activity有不同的操作很近发生,AccountSys的回调都有可能响应不过来。我一度想作一对多的观察者模式,因为可以同时响应多个。不过后来做完后,虽然我没改这个架构,但却从来没发生过问题,个人很庆幸,算完工了。 而AccountSys与DBHelper的调用与回调就没出现问题,因为Application只有一个AccountSys实例,而AccountSys又只有一个DBHelper实例..
第二个后来比较难处理的事情,是后来操作太多了,我只得给这些操作,无论是AccountSys面向UI的操作,还是DBHelper面向AccountSys的操作,都有好多了,而不同的调用面向不同的回调方法,这个真是蛮费事的啊。后来就是在回调接口switch case 完成的..例了十来个功能,后来也没有再重构了。
话说回调,当时发生了跨线程的回调了的问题,回调接口里边的函数是发生回调的代码那里执行的,如果发生回调的地方是别一个线程中,那回调的实现函数很可能和这个函数所在类不是一 个线程中。
----------
话说现在的IM项目,其实也是一样的,而且还多了更大范围的调用与回调,即跨进程的调用和回调。当然这个架构基本还是正确的,用messager的方法,大体也够用,也有一些问题。下边总结下下吧:
说到调用与回调,消息机制肯定撤不开了,在我这里的消息指的是什么呢?指的是调用时发过去的 信息 与回调时返回来的 信息,因为不同的调用方法与回调返回的信息是不同类型的,所以把这个地方统一好,还是非常重要的。比如这次的跨进程传送,我用的是ServiceCmd 进行传送,因为中途是要跨进程携带消息的,只能用Bundle,那我每个ServiceCmd都有用Bundle的初始化函数,这样我有数据的变动封装到了 那些Cmd中,无论是 客户端(对我来说是用BgService的Activity)还是服务端(就是Service),都没有显示出Cmd内部包装的变动。应该说,这个包装应该不是很完全,而且必然有很多改进甚至很大改进,但是我的想法初步落实了,而且我比较用心想了,我是蛮开心的。
还有上次那种可能取代的回调,被我用addListener与hashcode的方法化解了,我是认真构思、实现而且效果不错的,我非常开心,从此那个回调可能出问题的事就这样解决了。
......
要说上一部分的实现哪里需要改进,我个人认为Proxy与Service的switch,都把CMD给解了一下才去找功能,有没更好的,把传输给封装起来,调用和真正功能的封装在一起的可能?
还有比如Login那里,点多次重复发消息可能挂掉的问题,怎么样杜绝一下好。其实说到这里,我也有那觉得有必要作消息撤消(即发过去的东西不返回结果就可以了..)机制,还有多长时间不可以发重复功能的消息的机制。或者同样的消息,上一个没返回,下一个不能发出去的机制, 这几个作为比较操作逻辑完善的消息机制来说,非常重要。对于我现在这个Login的问题,很可能用第三个或第一个机制可以解决的。
第二就是BgService中的网络与数据库,大量的没开线程,这个显然不对了,我都忘了当年××APP的帐户系统时,我是怎么样所有网请和数据库都作线程的了,这里的话,concurrent包也线程池有必要用得更熟练一些。
-----------
说完消息机制后,也说说异步与UI的矛盾处理方法,其实也是因为今天的现象引起的。在开程序后我点登陆后,竟然有一二秒钟Dialog没有出来,我迫不急待其出来,于是又点了一下,于是挂了..,且不说挂的原因,我觉得UI反应灵敏太重要了,其实比如消息发送后等待回调的缓冲的地方你说多少100毫秒不是很重要的,对用户体验没太大影响的,相反前者影响很大。所以以后要坚决把UI响应及时响应出来,有可能卡的功能在其后哪怕立刻做也没问题,想想UC的UI,就是比360浏览器等的UI流畅一些,就好用很多的样子,以后我也要做UI的,这个经验太重要了。
此外,本次数据库的同步关键字和开闭问题也需要继续琢磨,我的模式还不清晰,还没想到非常好的办法,但要在这里记一下。
-----------
心血来潮,最近关于产品与技术的心得就先写这么一篇文章吧,异步处理系架构大局,系面向对象的典型运用,系MVC之明朗程度,我还要继续构思、实验、重构、学习。以后这种架构使用,我相信我会用得非常好的。
但是也是有一些东西值得思考的,已经做了很多项目了,应该有一些显示的经验或教训了,应该不至于像以前一样拿起来后,也没有太多的顾忌,直接就想架构后就直接开写了,今天下午在一次次RemoteService ANR 的苦闷中,我萌生了写这篇博客的念头。
还是先从今天引起反思的起因事件写吧,起因是为啥呢?RemoteService ANR了,那ANR是为什么呢? 很简单XMPP的网络请求数据,数据的写入数据库我都没有放入线程中写。那为什么我当年在构造这些函数时没有用线程+异步,也一年经验了怎么会犯这错误呢? 那回忆一下吧,其实在开始构造Remote Service时,我确实是想到了异步,但是当时并没有用,一是因为觉得可能没有这么严重吧(那时离作××APP的帐户系统时已经有些久远了,已经忘记了当时异步的极端重要性),二是对Remote Service的秉性不太熟悉,觉得一个后台进程,不开线程自已也是一个线程啊,相对我Activtiy完全是异步么..,当然现在明白这是完全完全错误的想法..Remote
Service 是Service 是组件,而不是线程,必然不是想像中那样用的。
---------
那于是今天先反思一下××APP帐户系统当时的架构,当时是单例的AccountSys作为了中枢系统,UI这端比如是一个Activity注册了AccountSys的回调接口之后,直接调用AccountSys的函数,而这个函数在另一个线程中从网络下载完后,就会处理存储更改数据库这类事情,处理数据库的类叫DBHelper,AccountSys也注册了DBHelper的一个回调接口,在线程中作完网络下载之后,其会调用DBHelper的函数进行数据库操作,但是这个操作也是异步的,操作后AccountSys会响应了DBHelper的回调接口。(这时说明DBHelper的数据库操作已经做完了,并告知了AccountSys了),这时AccountSys再执行其相对于Activity(即UI)的回调函数,这样UI便得到了最终网络和数据库操作完成了结果。
大体还记得那时出现了一些什么样的Bug,首先,因为AccountSys是单例的,同时只能一个AccountSys作为其回调对象,怕时有几个功能几乎很近发生时,会有回调被挤掉而不能完成。这种可能性理论上绝对是存在的,就算是一个Activity有不同的操作很近发生,AccountSys的回调都有可能响应不过来。我一度想作一对多的观察者模式,因为可以同时响应多个。不过后来做完后,虽然我没改这个架构,但却从来没发生过问题,个人很庆幸,算完工了。 而AccountSys与DBHelper的调用与回调就没出现问题,因为Application只有一个AccountSys实例,而AccountSys又只有一个DBHelper实例..
第二个后来比较难处理的事情,是后来操作太多了,我只得给这些操作,无论是AccountSys面向UI的操作,还是DBHelper面向AccountSys的操作,都有好多了,而不同的调用面向不同的回调方法,这个真是蛮费事的啊。后来就是在回调接口switch case 完成的..例了十来个功能,后来也没有再重构了。
话说回调,当时发生了跨线程的回调了的问题,回调接口里边的函数是发生回调的代码那里执行的,如果发生回调的地方是别一个线程中,那回调的实现函数很可能和这个函数所在类不是一 个线程中。
----------
话说现在的IM项目,其实也是一样的,而且还多了更大范围的调用与回调,即跨进程的调用和回调。当然这个架构基本还是正确的,用messager的方法,大体也够用,也有一些问题。下边总结下下吧:
说到调用与回调,消息机制肯定撤不开了,在我这里的消息指的是什么呢?指的是调用时发过去的 信息 与回调时返回来的 信息,因为不同的调用方法与回调返回的信息是不同类型的,所以把这个地方统一好,还是非常重要的。比如这次的跨进程传送,我用的是ServiceCmd 进行传送,因为中途是要跨进程携带消息的,只能用Bundle,那我每个ServiceCmd都有用Bundle的初始化函数,这样我有数据的变动封装到了 那些Cmd中,无论是 客户端(对我来说是用BgService的Activity)还是服务端(就是Service),都没有显示出Cmd内部包装的变动。应该说,这个包装应该不是很完全,而且必然有很多改进甚至很大改进,但是我的想法初步落实了,而且我比较用心想了,我是蛮开心的。
还有上次那种可能取代的回调,被我用addListener与hashcode的方法化解了,我是认真构思、实现而且效果不错的,我非常开心,从此那个回调可能出问题的事就这样解决了。
......
要说上一部分的实现哪里需要改进,我个人认为Proxy与Service的switch,都把CMD给解了一下才去找功能,有没更好的,把传输给封装起来,调用和真正功能的封装在一起的可能?
还有比如Login那里,点多次重复发消息可能挂掉的问题,怎么样杜绝一下好。其实说到这里,我也有那觉得有必要作消息撤消(即发过去的东西不返回结果就可以了..)机制,还有多长时间不可以发重复功能的消息的机制。或者同样的消息,上一个没返回,下一个不能发出去的机制, 这几个作为比较操作逻辑完善的消息机制来说,非常重要。对于我现在这个Login的问题,很可能用第三个或第一个机制可以解决的。
第二就是BgService中的网络与数据库,大量的没开线程,这个显然不对了,我都忘了当年××APP的帐户系统时,我是怎么样所有网请和数据库都作线程的了,这里的话,concurrent包也线程池有必要用得更熟练一些。
-----------
说完消息机制后,也说说异步与UI的矛盾处理方法,其实也是因为今天的现象引起的。在开程序后我点登陆后,竟然有一二秒钟Dialog没有出来,我迫不急待其出来,于是又点了一下,于是挂了..,且不说挂的原因,我觉得UI反应灵敏太重要了,其实比如消息发送后等待回调的缓冲的地方你说多少100毫秒不是很重要的,对用户体验没太大影响的,相反前者影响很大。所以以后要坚决把UI响应及时响应出来,有可能卡的功能在其后哪怕立刻做也没问题,想想UC的UI,就是比360浏览器等的UI流畅一些,就好用很多的样子,以后我也要做UI的,这个经验太重要了。
此外,本次数据库的同步关键字和开闭问题也需要继续琢磨,我的模式还不清晰,还没想到非常好的办法,但要在这里记一下。
-----------
心血来潮,最近关于产品与技术的心得就先写这么一篇文章吧,异步处理系架构大局,系面向对象的典型运用,系MVC之明朗程度,我还要继续构思、实验、重构、学习。以后这种架构使用,我相信我会用得非常好的。
相关文章推荐
- 关于选择移动开发平台(android,ios,wp7)的一些看法
- 关于选择移动开发平台(android,ios,wp7)的一些看法
- 关于逆向工程的一些心得
- 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET - 关于AgileEAS.NET的一些补充说明
- Android关于9patch图片的注意事项和其他一些心得
- 关于Microsoft Report RDL的一些心得及Hack经验
- 关于GRIDVIEW与DETAILSVIEW的一些心得(包含DROPDOWNLIST的配合)
- 关于NSTask使用的一些心得体会
- 一些关于Liferay的使用心得
- 中国移动Mas短信平台开发增值服务的一些心得
- 关于适配的一些小小心得(iOS7)
- 关于平台研发的一些想法
- 关于javascript类的编写与继承的一些心得
- 关于 Android 混淆的一些心得
- 关于sql的一些学习心得
- 关于qte illegal instruction的一些心得
- 关于windows句柄机制的一些心得体会
- 服务器端编程心得(六)—— 关于网络编程的一些实用技巧和细节
- 关于iOS系统里录音的一些设置的心得
- 关于com工程依赖的一些总结