海外APP推送(上篇):厂商通道与谷歌FCM通道的差异

cef217dd26b19178bc8b1944f1490baf.jpeg

作者:极光高级工程师——史坤坤

企业出海图景

在疫情持续,叠加复杂多变的国际贸易环境下,中国对外直接投资流量和存量连续四年稳居全球前三,近八成中国企业将维持和扩大对外投资意向,看好对外投资前景。

企业出海,第一要务就是要建立与用户的触达通道。在APP环境之外,海外触达用户的通道与国内用户略有区别,海外是以邮件为主要的通道,而国内主要是以短信为主,辅以微信等社交通道。在APP环境之内,海外与国内触达用户的区别不大,均是以APP推送为主。

接下来,我们着重从海外APP推送通道来做一些对比与分析。

APP消息推送通道现状

在海外,手机厂商除苹果外,安卓仍然以三星为领头羊,独占19%的市场份额。小米、OPPO、Vivo、realme紧随其后,市场份额占比分别为12%、9%、8%以及6%。

627e66be14b3a8dd3ed1adec0152e786.png

图一:2021年第四季度全球智能手机出货量报告(数据来自市调机构Conuterpoint Research)

企业APP的消息触达用户的通道,最重要的仍然还是推送通知消息。各个头部厂商对Android原生系统均有所定制,但与国内环境还是有所区别。

在中国大陆,谷歌受地域限制,无法使用谷歌相关服务,国内厂商对GMS服务套件进行了系统层的阉割,谷歌官方的FCM推送通道也相应的无法使用。进而替代的是各个厂商自己的厂商通道。顾名思义,厂商通道就是指手机硬件厂商提供的系统级别的推送通道,因为是系统服务,随着设备开机后就一直存在着,有效的保证了推送通道长连接的高可用性。

在海外,由于安卓系统默认支持谷歌FCM通道,且网络环境不受地域限制,因此厂商未对出口海外版的手机进行GMS的阉割,而是保留厂商通道与谷歌FCM通道共存的方式。谷歌FCM通道,是安卓系统自带的通道服务,与谷歌Firebase后台保持长连接,服务归属是谷歌而非设备厂商。

经实际测试、同时与厂商官方技术沟通后,总结关于通知通道的使用情况如下:

98a4cac7333d1444f51f2c53051c6a3d.png

厂商通道与谷歌FCM通道的区别

那么,既然海外的Google服务是不受限制的,为什么厂商还要保留两个通道呢?他们有什么具体的区别吗?确实是存在一些区别。

区别一:就是上边提到的通道归属服务方不同,厂商通道由硬件设备厂商提供服务,谷歌FCM通道由谷歌官方提供服务。

区别二:厂商通道,在网络通畅且推送消息内容合法的情况下,通过厂商通道推送消息给该厂商设备,不论应用进程是否存活,都能保证消息可以推送到位。所以,厂商通道是消息高效触达的一种保障。同时,也对企业用户的拉活、促新、留存有一定的提升。而FCM通道,通过Firebase后台推送消息给安卓设备时,设备收到消息后,会先根据应用的某种状态来决定是否展示消息。如果APP进程被用户主动杀死,将不会继续进行展示推送消息。

对于这个规则,起初我们也是持有怀疑态度,如果这样的话,那与APP自己实现消息推送相比,就没有高可用的通道服务的优势了,难道只是为了帮助开发者简化推送服务的实现流程,降低开发成本?带着这个疑问,我们展开了专项测试和分析。分析过程如下:

  • 验证进程存活与被杀死情况下,消息的展示情况的现象。

  • 分析消息的生命周期状态

  • 深入分析系统源码、GMS源码、FCM源码

  • 总结结论

下面是具体的分析过程,涉及到系统源码的分析,如果不感兴趣可略过阅读,直接看最后总结的结论。

01

验证进程存活与被杀死情况下,消息的展示情况的现象

a. 退入后台,无操作停留2小时

通过usb连接手机,进入ADB模式,执行ps命令后,进程仍然存在,说明并未被系统回收资源。此时发送推送消息,如预期,通知消息正常展示。

b. 退入后台,通过最近任务,滑动杀死APP

416dbd5e9c7b68294100f3f9708b774c.png

同样,进入ADB后,通过ps命令查看进程状态,进程已不存在,但不确定资源是否被系统及时回收。此时发送推送消息,通知消息能正常展示。还比较符合厂商通道的优势特征。

c.  进入应用详情,强行停止APP

3e9be7b85954c1416fa9a4cbdd24c176.png

不出意料的,进程肯定已经不存在了,ps命令查看也是如此。同样的,不能确定资源是否被系统及时回收。此时发送推送消息,通知消息却不能正常展示。由此推测,FCM通道不依赖APP的进程是否存活。这个特点,是优于APP自己实现推送通知的。

d. 重启手机

重启手机后,由于应用已没有接收重启系统的广播权限,进程肯定已经不存在了,同时,资源肯定也是被系统回收了的。此时发送推送消息,通知依然能正常展示。由此进一步确认,系统缓存了应用的某种状态,FCM会依据该状态来决定是否展示通知。

02

分析消息的生命周期状态

有了以上试验的现象,那么接下来重点分析下为什么强行停止APP后,就不能正常收到通知并展示了。

首先看推送API的响应,正常。推送任务已提交至谷歌Firebase后台,姑且认为服务器已下发到设备。

通过adb logcat >log.log 抓取现场系统日志,在log中有以下打印:

16600 16600 W GCM : broadcast intent callback: result=CANCELLED forIntent { act=com.google.android.c2dm.intent.RECEIVE pkg=cn.jiguang.junion.jpushtestdemo (has extras) }

确认消息已正常送达到了设备,因此怀疑GMS的消息广播就没有正常发出来。

03

深入分析系统源码、GMS源码、FCM反编译代码

先根据FCM 方法调用链,从消息分发处入手往上跟进,确认其调用步骤。

a.  FirebaseMessagingService
在系统源码中跟踪到FirebaseMessagingService 负责分发通知消息到SDK。

7eee5b7ab24aa2823fee3ee0637839e6.png

ea879ec8f473b18f06550ec34c6d04b2.png

0108612f3888095bac1f4f0be735348a.png

b.  EnhancedIntentService 负责解析处理收到的消息

9024b83f8201d28afe4ba0e669b2b09b.png

6f248966b98f5b32ccc4e6a105c9d132.png

c.  继续分析消息是哪里接收来的,跟踪到是通过AIDL形式把广播中的消息传到Service中的

6dc4c6dd01f41eb97c43cfc79dc31771.png

然后发送到FirebaseInstanceIdReceiver

297b7c7bb84ecd2838cb0e43398b212d.png

d.  最终的广播来源CloudMessagingReceiver

4e71b93f0feb1ad0e4453bf83377582c.png

因此可以明确知道:FCM 的消息也是从广播来的。

04

总结结论

最终,在AMS中找到了答案。应用被用户主动kill后,系统直接把死亡进程所属的广播,都直接过滤掉了,从而不对其发送广播。
在Android系统中,应用被用户主动kill后,在ams 中会调用finishForceStopPackageLocked()中 发送内部广播:ACTION_PACKAGE_RESTARTED, 它会限制包的自启或者通知移除等等。而广播是通过sendBroadcast来发送的,在AMS broadcastIntentLocked 中,明确添加了intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);该Flag后续会从系统中查找缓存,过滤广播的代码:

registeredReceivers =
mReceiverResolver.queryIntent(intent,resolvedType, false /*defaultOnly*/, userId);


在IntentResolver.queryIntent方法内部有调用:

final boolean excludingStopped = intent.isExcludingStopped();
if (excludingStopped && isFilterStopped(filter, userId)) {  -------这里会过滤Stopped 和进程Stop的
    if (debug) {
         Slog.v(TAG, " Filter's target is stopped; skipping");
    }
}

isExcludingStopped()的定义代码:

public boolean isExcludingStopped() {
  return (mFlags&(FLAG_EXCLUDE_STOPPED_PACKAGES|FLAG_INCLUDE_STOPPED_PACKAGES))== FLAG_EXCLUDE_STOPPED_PACKAGES;
}

官方的issues也有类似的官方回复,感兴趣的可以看下:

a46d254cf1c2a0665240bd7079f70ca5.png

引自:https://github.com/firebase/firebase-android-sdk/issues/2917  

更多关于海外厂商通道的集成方法,请看下回分解。

d22a9494e085ad8396f6a592615bb4ab.gif

关于极光

极光(Aurora Mobile,纳斯达克股票代码:JG)成立于2011年,是中国领先的客户互动和营销科技服务商。成立之初,极光专注于为企业提供稳定高效的消息推送服务,凭借先发优势,已经成长为市场份额遥遥领先的移动消息推送服务商。随着企业对客户触达和营销增长需求的不断加强,极光前瞻性地推出了消息云和营销云等解决方案,帮助企业实现多渠道的客户触达和互动需求,以及人工智能和大数据驱动的营销科技应用,助力企业数字化转型。

8ea195366a48f0dd647033eee9365078.png

联系我们

添加企业微信,

专属客户经理一对一解答

“阅读全文”,了解更多极光资讯

609aba8e933452bca231bdf7ca30e19c.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值