移动网络下的耗电
  Google在Optimizing Downloads for Efficient Network Access中提到了一个叫Radio State Machine的东西.


  mobile radio state machine

  说的应该是基带的工作状态, 在Radio Standby下几乎不耗电, 但是一旦有需要处理的事情, 比如手机里某个app要访问网络(从上一节可以推测: 收到RRC指令也会导致唤醒), 会进入到Radio Full Power中, 由Standby转为Full Power这一唤醒过程很耗电, Full Power下基带空闲后5s进入Radio Low Power, 如果又空闲12s才进入Standby. 主要的意思是不要频繁的唤醒基带去请求网络, 因为只要一唤醒, 至少会让基带在Full Power下工作5s, 在Low Power下工作12s, 而且唤醒过程很耗电. 所以在移动网络下, 心跳需要尽量的慢才好, 不过以当前这种情况, 想慢下来几乎不可能.
  不过这也带来另外一个问题, 假如手机里有10个应用, 每个应用都发送心跳包, 每个应用的服务器都可能唤醒手机, 那手机还休不休眠了?
  实际实现遇到的问题
  了解完了我开始动手做demo, 服务器使用Apache的Mina, 客户端也用这个
  Mina
  这个框架挺好用, 是遇到些很奇怪的事情, 我两天前看的, 所以也可能是我自己的问题.
  一个是Android端发一个汉字给服务器, 服务器filter崩溃, 发超过一个汉字, 客户端filter崩溃, 写个IoFilter做一下编解码好了. 另外User Guide里面的代码也有错误. 第二个是IoSessionConfig的写超时设置了完全不起作用.
  小米手机的神奇Socket
  后来又发现客户端只要在后台超过一定时间, 对socket的写操作会变得非常诡异, 表现为socket把数据吞了, 告知应用数据已经被对方接收, 但是服务器什么都没收到, 而且服务器发送的消息客户端也收不到. 只要让app进到前台, 之前消失的数据会一股脑发给服务器, 客户端会收到服务器重传的消息.
  我开始还以为是Android的休眠机制把wifi断了, 我把各种WifiLock, WakeLock都持有了, 还是出这种情况. 后来无意间发现小米针对每个app都有个后台运行时允许联网的开关, 我把它打开了, 果然好了一阵子, 后来又开始重复之前的情况, 我还以为是Mina的IO线程被kill了还是怎么, 用DDMS看了线程信息没问题. 不放心, 又用纯Socket实现了客户端, 还是有问题, 再在之前的基础上加上1分钟的心跳, 还是有问题.
  小米手机的神奇bug
  这次真是我运气好, 我又看了一眼后台运行时允许联网的开关, 发现demo app的这个开关刚刚还被我打开了, 这下又关上了, 我怀疑是小米的这个功能有bug, 我是记得有小米员工提到这东西有服务器下发白名单的, 我认为是服务器下发数据把我的改动给覆盖了, 我把几个app的后台联网关了, 重启手机之后, 他们又开了.
  后我改了个10s的心跳间隔, 在心跳的时候, 把后台允许联网关掉, 复现了那个神奇的socket行为, 大概确定是MIUI的bug.
  睡了一觉起来, MIUI的工程师联系了我, 确认是bug. 顺便提醒一下用小米做测试机的开发者和用户, 这个bug的临时解决方案是: 用神隐模式里的自定义配置, 把自己想改的设置好行.
  想起一年前什么都不懂跑去小米面试好笑, 我这水平完全是坑人, 然而没想到这次被小米坑了.
  我心中佳的推送技术
  RRC那套东西, 你懂的, 基带Standby模式下也保持着的连接.