push方案

poll:客户端定时去服务器端检查

push:客户端和服务器维持一个连接,服务器有新内容推送给客户端

实现对比

1、XMPPExtensible Messaging and Presence Protocol,前称Jabber[1])是一种以XML为基础的开放式实时通信协议,是经由互联网工程工作小组(IETF)通过的互联网标准。XMPP因为被Google Talk应用而被广大网民所接触(米聊也是基于XMPP协议)。

http://zh.wikipedia.org/wiki/XMPP

优点:基于XML,扩展性强;周边生态成熟,有很多开源方案,如AndroidPn,也可以自己来实现,Smack做客户端,Openfire作为服务端实现客户端和服务端实时通信;

缺点:协议较复杂、冗余(基于XML)、费流量

2、GCM服务(Google Cloud Messaging)

简介:Google推出的云消息服务,即第二代的G2DM,基于XMPP协议实现。

优点:Google提供的服务、原生、简单,无需实现和部署服务端。

缺点:Android版本限制(必须大于2.2版本),该服务在国内不够稳定、需要用户绑定Google帐号,受限于Google。

淘宝有用到,客户端根据当前环境选择GCM或定制Push服务。

3、MQTT协议(更多信息见:http://mqtt.org/)

简介:轻量级的、基于代理的“发布/订阅”模式的消息传输协议。

优点:协议简洁、小巧、可扩展性强、省流量、省电,目前已经应用到企业领域(参考:http://mqtt.org/software),且已有C++版的服务端组件rsmb。

缺点:不够成熟、实现较复杂、服务端组件rsmb不开源

4、基于Socket连接,自定义协议

维护一个客户端到服务器长连接,自定义数据交换格式,实现Push。

优点:可控性强,按自身业务随意定制,实时性强

缺点:实现复杂

极光推送、信鸽等Push基于TCP协议自己定制

5、HTTP轮循方式

简介:定时向HTTP服务端接口(Web Service API)获取最新消息。

优点:实现简单、可控性强

缺点:实时性差。

服务器主动Push的方式需要保持链路的连通性,因运营商网关的关系,五分钟左右会回收没有使用的连接,所以需要心跳包保活。

Push方案选择

结合自身业务需求,选择了通过HTTP轮询方案。拉取Push没有那么高的实时性要求,长连接保活需要高频率(4-5分钟发送一次心跳包)的发送心跳包,耗电;产品需求是Push展示时间为8-24点,默认轮询周期是4小时,Push一般是前一天配置好,可最大可能的被拉取到。

轮询那么必须有个定时机制,定时唤醒客户端去服务器拉取

Android定时机制对比

Android定时机制有Handler、Timer、AlarmManager。

Handler和AlarmManager的区别:AlarmManager可以通过PendingIntent唤醒未启动的进程,而Handler定时信息随着进程被杀消失,Handler定时依赖于epoll的timeout,AlarmManagerService依赖于RTC时钟。如果程序被强制停止后,基于安全机制AlarmManager注册的定时器会被清空(防止恶意应用频繁唤醒)。

 The Alarm Manager is intended for cases where youwant to have your application code run at a specific time, even if yourapplication is not currently running. For normal timing operations (ticks,timeouts, etc) it is easier and much more efficient to useHandler

定时器注册

定时器需要注册,如何选取注册事件?

为了保证定时器注册成功率,尽可能选高频率的系统事件,如开机广播(Android 系统版本小于2.3),网络切换事件、时间改变事件(DateChanged、TimeChanged,当时注册这两个事件是为了搞定测试,但是被坑的也不浅)

DateTimeChanged和TimeChanged

这两个事件在系统启动后,启动AlarmManagerService服务,同时由AlarmManagerService调度,

DateChanged一天触发一次,12点左右触发,由于程序设计问题,收到DateChanged事件,会直接触发拉取更新或注册定时器,刚发布新版本请求挺均匀的,过了一两天就开始有大量请求聚集在午夜,这也就是为什么每天12点会有高峰(后面会对定时器原理做个分享)

请求聚集

上面已经举了个因DateTimeChanged事件聚集,导致客户端拉取push请求聚集的例子。可以用具体算法把拉取周期打散,考虑到用户使用客户端是一个离散事件,首次启动、或网络切换的时候注册定时器,这样就能保证定时器触发的时间在一个周期内是离散的,同时也保证代码的简洁。

系统里有大量未触发的Alarm

产商投诉我们的的AlarmManager有3000多个PendingIntent未发送,而且还在频繁注册,起初没留意,以为是产商系统问题,装了一个在测试机上面,dump Alarm信息后发现没有说的那么多,后来根据产商提示,频繁网络切换,频繁灭屏(Wifi自动更新依赖于该事件),确实会有大量的PendingIntent,但是一旦触发一次Alarm,具有相同Action的PendingIntent一起被系统清除(这个问题还没有想清楚,看代码也没看出为啥)。

AlarmManager在注册定时事件的时候会根据PendingIntent作为判断依据,如果之前注册过一个相同的PendingIntent,那么再注册一次会把前一个给取消,用后面的给替换。

PendingIntent有三个可选参数,FLAG_CANCEL_CURRENT,会把系统缓存的PendingIntentRecord对象先remove,然后再创建一个新的PendingIntent对象。前后两次创建的PendingIntent比较不相等,造成这个问题,将FLAG改成FlAG_UPDATE_CURRENT问题得以解决。

注册了事件拉取逻辑?

每隔4小时轮询服务器,联网用户拉取比率只有80-85%左右,没网络就错过一次机会,改策略为间隔大于4小时有网络就拉,联网用户拉取比例99%

Push无法展示

安全软件

拦截应用自启动,发push,此动作不一定需要手机root,360能对特定系统漏洞提权,获取root权限,组织应用接收系统事件

系统内置优化工具:已知新蜂Rom,X产商5860S,优化后无法收到Push

现象:dumsys alarm定时器工作正常,但是就是接收不到广播,一番google后发现有人提及4.0后可以禁用Android 四大组件(前提是有root权限),查看/data/system/packages.xml,发现广播接收器被禁用。

安全软件或是优化工具,会对注册系统广播的组件进行分析,禁用;更高级的是获取root后hook,然后替换Android框架通知核心处理逻辑,根据白名单禁止通知,金山早期版本有这么做过。

规避:不要‘高危’广播,或者将这类广播和业务处理逻辑Receiver分开。

Android限制

非系统应用最多只能在通知栏展示50个通知,通知被用户cancel、应用进程被杀或者强制停止后,不再有该限制。

规避:很少有产品会这么做,一般发广播都是会复用REQUEST ID,这里只是澄清有这种限制

系统本身问题

产商OS问题,安装后就会禁用接收了BOOT_RECEIVER广播的组件

Push展示数字不准确

由于后台更新服务是有损的,加之程序逻辑bug,每次进入商店提示应用更新的Push数字差异比较大,程序Bug Fix后出现概率小了些,最终定位到后台返回更新数不准确才算告一段落。

架构

定时事件触发后,加上系统事件这么多事件,如何统一接受、处理、分发?

总结:

Push核心集中在定时任务模块,定时器问题排查一看定时器有没有问题(dumpsys alarm),二看广播接收器有没有问题,看log或看组件是否被禁用(/data/system/packages.xml)。多了解一些Android背后系统实现,解决一些疑难问题比较有帮助。文档写的再好也会有笔误或更新不及时。

Android Push实现总结相关推荐

  1. 3 分钟搞定 Android Push

    在 Android 上,要实现 Push 功能可没有那么简单! 众所周知的原因是,Android 官方的推送服务 GCM 在国内手机上用不了.所以很多国内的开发者,不得不去使用 AndroidPN 这 ...

  2. jpush android 离线推送,JPush极光推送3分钟搞定Android Push

    在 Android 上,要实现 Push 功能可没有那么简单! 众所周知的原因是,Android 官方的推送服务 GCM 在国内手机上用不了.所以很多国内的开发者,不得不去使用 AndroidPN 这 ...

  3. android提权system,Android push app to /system/app/

    背景 个人想要了解一下关于系统权限方面的知识,而我又天真地以为只要把app push到/system/app/目录下,app就有系统签名了,也就能获取到系统权限了.但是其实这样是不行的...算了,学一 ...

  4. Android Push哪家强——分析豌豆荚1400个APP

    背景 由于国内 Android 生态百家争鸣(其实TM就是混乱),各个手机厂家对 Android Rom 进行了深度定制,衍生出了各种 Android 系统.由于国内无法使用 Google GCM 服 ...

  5. Android push原理

    一.消息推送定义 在用户未打开App时,App主动向用户推送服务器最新消息.如下图: 二.App从服务器获取最新消息有两种基本方式 1.主动获取方式(Pull) 客户端隔固定时间主动向服务器获取信息, ...

  6. android push sdk6,JPush SDK 华为通道集成指南

    JPush SDK 华为通道集成指南 概述 在国内 Android 生态中,推送通道都是由终端与云端之间的长链接来维持,严重依赖于应用进程的存活状态.如今一些手机厂家会在自家 rom 中做系统级别的推 ...

  7. android、apple PUSH 异同比较

    相同点: 实现思路. 自己的服务器与apple(APNS)或google PUSH服务器进行通信,PUSH服务器依据相应的条件(如:当前终端在线),向相应的终端设备发送PUSH信息. 终端设备通过自己 ...

  8. android 小米,华为,百度Push封装(准备阶段)

    前:本文为QiaoJim原创,转载请附原文链接,谢谢合作! http://blog.csdn.net/qiao_jim/article/details/73146673 --------------- ...

  9. [业务知识]push原理总结(包含iOS,Android,极光,厂商)

    Push在产品运营的作用 定期的推送,可以让更多的用户看到并使用app,对于app运营是很有效果的.可提升产品活跃度.带动功能模块使用率.带来有效的订单以及增加产品粘性.唤醒沉睡用户等. 目的: 在用 ...

最新文章

  1. R语言window函数提取时序数据数据子集(subset):使用xts包将dataframe数据转化为时间序列数据(time series)、使用window函数从时间序列对象中提取数据子集
  2. Chrome资深粉热衷的10个必备扩展程序
  3. linux /bin/sh -c的用途
  4. Map和hashmap
  5. mysql 随机查询数据
  6. 通过SQL Server操作MySQL的步骤和方法
  7. java 操作日志设计_日志系统新贵 Loki,确实比笨重的ELK轻
  8. EDA风格与Reactor模式
  9. 详解Java动态代理机制
  10. asp.net写验证码
  11. 注解 @EnableFeignClients 与 @ComponentScan 有冲突
  12. 预科计算机考试试题,少数民族预科计算机应用基础课程机考试题库的
  13. 2021FME博客大赛 —— FME在道路实景建模中的应用研究
  14. iTunes Windows 历史版本下载
  15. 华为服务器查看虚拟ip,裸金属服务器管理虚拟IP地址
  16. ue4设置默认打开的地图和默认游戏模式
  17. 《电路/电路原理》—戴维宁(南)定理实战演练
  18. PC微信逆向--定位备份sqlite数据库相关函数
  19. 【带你敲】演讲比赛流程管理系统
  20. 词典查询APP开发设计方案

热门文章

  1. TLF 0day SERVER 列表
  2. java gui编程 计算器_Matlab-GUI编程:简单计算器的实现
  3. maya2018的uv导入和导出
  4. 【LaTex】在 LaTex 中优雅地插入行内和行间代码
  5. 使用JS模拟键盘、鼠标操作
  6. Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
  7. Multisim基础 NPN型三极管 简单放大电路示例
  8. C++的灵魂核心-类
  9. Android aab文件签名过程
  10. Mybatis引用静态常量或者枚举类型