专栏名称: 开发者全社区
分享和推送Java/Android方向的技术和文章,让你成为这方面的大牛,让你每天都成长一点。同时,我们也会邀请BAT的大牛分享原创!
目录
相关文章推荐
开发者全社区  ·  AI 公司董事长...十几刀...刺死 ... ·  昨天  
开发者全社区  ·  太奇葩了!离职后被前公司调查去向...... ·  昨天  
开发者全社区  ·  北舞身材管理曝光 ·  昨天  
开发者全社区  ·  浙大副教授选妃的瓜 ·  2 天前  
开发者全社区  ·  37岁被腾讯裁员,找了两个月只有两 ... ·  3 天前  
51好读  ›  专栏  ›  开发者全社区

关于Android推送,你应该知道的都在这!

开发者全社区  · 公众号  · android  · 2017-04-24 10:01

正文

相关阅读:

吊炸天!74款APP完整源码!

Android中多线程的使用四种方式最全总结

那些年收藏的很实用的Android开源库集合(工具)

来源:即可技术团队

今天来讲讲推送这件小事,事虽小,要做好却不容易。

推送难,难于上青天。

我们在讨论 Android 手机上的推送时,大多数情况是在说集成第三方推送,因为即使是像微信这样的大厂,也需要厂商加到启动白名单里才能保持在线。

iOS 手机使用 APNs( Apple Push Notification service)进行推送,而 Android 手机,也是有 GCM (Google Cloud Messaging)作为 Google 官方的推送支持的,但是在国内需要翻墙才能使用,并且需要手机安装了 Google Service ,条件比较苛刻。

这样一来,国产手机的推送就成了个问题,也带了机会。

微信由于有国际版,将 GCM 作为辅助公共通道,但仅用于激活微信自己的 Push 通道,并没有通过 GCM 来传递数据,这点也是为了复用心跳的优化策略和数据处理逻辑。

GCM 最新版本叫 FCM (Firebase Cloud Messaging)

推送的实现方式

总结一下几种推送实现方式,其中有些我们只要了解即可,因为属于历史解决方案,现在已经被废弃掉了。

1. 轮询

客户端定期询问服务器有没有新的消息,这种方式最大的缺点就是 性能 实时性 的矛盾,轮询时间过长和过短都不好。

2. 短信

这种方式还没出生就不被允许了,首先运营商不会配合,其次拦截手机短信本身就是一个高危权限,大多数用户不会买单。

3. 长连

目前最通用的方案,客户端与服务端建立 TCP 长连,定时发送心跳包保活,有新消息时服务端通过该长连通道进行推送。

这里再简单说明一下长连和心跳包。

长连接 就是建立连接之后,双方互相发送数据,,发完了也不主动断开连接。

但是在某些情况下长连会断开,问题就在断开这件事上,而且这件事必须是由客户端知道,因为客户端是可以重连服务器的,服务器却没法再联系上客户端。这样才确定了 心跳包 必须由客户端发给服务器。所以心跳包的作用就是告诉服务端客户端还活着,如果服务端挂了,客户端能知道,所以 保活 说的是保持两边都活着。

上面说的某些情况中, NAT 超时 算是一个典型的例子。

因为 IPv4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet ,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。所以长连接心跳间隔必须要 小于 NAT 超时时间(aging-time),如果超过老化时间不做心跳, TCP 长连接链路就会中断,服务器就无法发消息给客户端,只能等到客户端下次心跳失败后,重建连接才能取到消息。

有了长连,即使在休眠模式下,有推送消息过来,也能唤醒 Android 系统,这是由系统机制决定的,我们这里只要知道结论就好。

想要了解更多的可以去看文末的 参考资料

推送的指标

在接入推送服务时有几个核心指标需要考量:

1. 在线率

在线率 = 在线用户数 / 总用户数

推送服务后台保持在线的方法

  • Push 进程常驻后台,需要用户手动让应用常驻

  • 共享连接通道的方式,比如极光或者个推,通过共享连接,当应用有推送到达时,唤起该应用

显然,后者在体验上更加接近 GCM 。

2. 到达率

到达率 = 实际到达数 / 目标用户数

在线数 -> 目标用户数 -> 成功下发数,如果后端的计算或调用出现问题这两个数据就会不准确

在线数 -> 实际到达数 -> 展示数,数据收到后,是否展示要看用户有没有打开该应用的允许通知的开关,可以通过如下方法判断

notificationManagerCompat.areNotificationsEnabled();

3. 耗电量

耗电量受到很多方面的影响,如果收到推送比较多,打开应用比较频繁,耗电量自然也会上去不少,但这个用户是可以接受的。以下几个耗电量的因素用户是比较反感的:

  • 应用间互相唤醒产生的耗电,因为这个耗电是别的应用的,用户本来没有意图要去打开

  • 错误重试造成的耗电,重试策略的优化包括重试时间的累加和重置

推送选型

上面提到,我们这里聊的推送,是 第三方推送 ,那有开发者要问了,为什么不自己做推送?自己做不是不行,但需要考虑几个问题:

  • 开发成本问题, ROI 是否可以接受

  • 如果不加入白名单,那么一旦应用被彻底杀掉,是没人给你吟唱复活魔法( 互相唤起 )的

第三方推送主要有厂商推送和非厂商推送

  • 华为、小米、魅族推送

  • 个推、极光、友盟

  • 阿里、腾讯、百度

其中,选型的几个因素

  • 厂商推送 通知 是否系统通道(所有厂商支持)

  • 厂商推送 透传 是否系统通道(仅魅族)

  • 非厂商推送的市场占有率(影响共享连接 互相唤起 的概率)

如何在 Android 手机中查看某个应用使用的是什么推送?

adb shell dumpsys activity services | grep igexin

可以看到,这几个应用都在使用个推

大众点评、宝宝树、饿了么、滴滴、简书、领英、 WPS Office 、格瓦拉。

推送接入

如何解耦

由于各个推送 sdk 接口定义不同,为了减少耦合,我们采用多 module 的形式进行接入。

  • app

  • jikepush

    • PushServiceImpl

  • push_厂商1

    • PushPlatformImpl

  • push_厂商2

    • PushPlatformImpl

  • push_非厂商

    • PushPlatformImpl

  • jikecore

    • PushService

    • PushPlatform

在 app 层通过注册的方式添加需要的 PushPlatform ,之后通过 PushService 接口来进行调用,具体的启动和切换的实现放在 PushServiceImpl 。







请到「今天看啥」查看全文