
恰卡塔雅山(Chacaltaya Mountain)。去过的地方就九寨沟有这么高的山,不过没有这里的奇峰俊岭,满目疮痍。

恰卡塔雅山(Chacaltaya Mountain)。去过的地方就九寨沟有这么高的山,不过没有这里的奇峰俊岭,满目疮痍。
既然有了这么好的通知工具(异步的哦),那一般的app如何使用这个服务呢?
可惜的是由于这部分是闭源的代码,而且SDK中这个服务也是undocument的(这是指1.6中的情况,2.0好像加上了不少同步的功能,待查)。消息我们倒是可以收到的,使用Android里面Reciver的东西,Intent为android.intent.action.GTALK_DATA_MESSAGE_RECEIVED,具体可以参考源代码里面的SubscribedFeedsBroadcastReceiver这个类。但是如何发生消息呢?发到GTalk么?实验后无果,Android把这些消息都当作chat类型的消息了,反正那个Reciver是收不到的。
我们可以另起炉灶用Smack库做一个XMPP的客户端,这个客户端要作为一个Service运行。Push services: Implementing persistent mobile TCP connections这里提供了一个例子,实现了一个保持连接状态的Socket连接。按照这篇文章里面的说法,Android系统会隔一段时间后kill掉service,然后启动service,更关键的是在手机CPU处于sleep时,是接受不到push过来的数据,这时候必须使用AlarmManager来定时叫醒CPU(无亲自验证)。
对于Android使用Smack包,Android – Just use Smack API for XMPP这篇文章有详细描述。虽然Android里面包含了Smack,但是还是不能直接使用(可能对Smack做了修改)。同样对Smack我们也要打上patch才能在Android下面是用,前面的文章中有提供patch,查看了下,主要是把xmlpull的xmlparser换成了kxml2(这个应该是Android内置的)。diff对新的Smack代码也可是使用。
综合上面两部分的代码,就作出了一个持续连接的XMPP客户端。
Android有个让人赞赏的特征:实时的同步。
1)如果你有新的Gmail邮件,手机可以马上收到邮件通知,这个中间可能有2,3秒的延迟,一般感觉还是很及时的;
2)如果你的联系人和Google Contanct是关联的话,你用桌面浏览器访问Gmail,修改联系人信息,很快新的联系人信息就会同步到你手机上。
最简单的实现可能用轮询(Polling)了,但这种方式有缺点:一则增大服务器的负担,想想如果每个客户端每隔半小时访问服务器,而大多数情况下服务器是没有更新数据的,对比起来服务器的负担就很浪费了,半小时的时间又很难做到实时的更新…;二则对于手机这种客户端,轮询浪费电源这个手机最宝贵的资源。
解决的方式是长连接,有好几种,这里讲的比较全面:超越轮询?考虑PubSub、Push和MOM。也可用类似Comet的长连接,而Android里面用的是XMPP。
当运行了上面的第二种操作后,在logcat里面可以看到如下log:
11-02 21:45:08.706: DEBUG/Smack/Packet(148): [READ] <message id=”xL62aX-26″ stanza-id=”269508591457″ to=”fkpwolf@gmail.com/androidfCv23kaFEJQd0Mc” from=”gmail.com” type=”headline”><data xmlns=”google:mobile:data” category=”GSYNC_TICKLE” token=”http://www.google.com/m8/feeds/contacts/fkpwolf@gmail.com/base2_property-android” from-trusted-server=”true”><app-data key=”account” value=”fkpwolf@gmail.com” /></data></message>
网上查找一番后会发现Smack是XMPP一个比较流行的客户端lib,而这里面的message正是XMPP一种类型为headline的消息,为通知类的消息,而聊天的则为chat类型。虽然Smack是开源的,Android里面的这部分做的很private,search代码没有任何发现。Google虽然不做恶,但是也不是做善事的。
平时喜欢看《动物世界》,里面有类镜头经常出现:小动物们齿牙咧嘴相互打闹追逐。解说说这虽然只是玩耍,但是其实是在训练捕食或搏斗的技巧。所以说,寓教于乐也是有其进化论上的意义的,现在有的家长一般都让孩子在小时候自己玩耍,不要给太多的功课,其实是一种明智的做法。
如果没有玩耍,没有训练,那真正的场面来的时候就没有准备,人会感觉紧张。玩就是一种模仿的过程,事情得在发生前多次尝试过,来的时候才会更有把握,所谓做啥事得“有模有样”。
学习是否就全是模仿的过程呢?
《代码之美》的作者在序中说:“建筑师需要观摩建筑物,作曲家需要研习他人的作品,而程序员 – 他们只有在需要修改BUG时才会去阅读他人的代码;即使在这个时候,他们也会尽可能减少阅读量。” 所言极是啊!对于程序员,光知道理论的知识是远远不够的,得用到实际中。小到试用某个新的framework,把玩某个刚出来的操作系统,大到学习Linux Kernel代码,都是学习和模仿的过程。对于软件这种工程类技术,有了熟练的模仿,才会有创新。
2010.1.8 add: 前天在广播上听到一句话:要玩,然后在玩中知道自己喜欢的是什么!显然这句话比我说的要高明很多啊。