微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)

http://www.52im.net/thread-210-1-1.html

哪些部分需要“保活”?


按照我们的理解包含两部分:


进程保活概述


在Android系统里,进程被杀的原因通常为以下几个方面:

  • a. 应用Crash
  • b. 系统回收内存
  • c. 用户触发
  • d. 第三方root权限app.

原因a可以单独作为一个课题研究。原因c、d目前在微信上没有特殊处理。这里讨论的就是如何应对Android Low Memory Killer。

进程保活实施:进程拆分


微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)_0 (3).png

上图表述的是微信主要的几个进程:

  • a. push主要用于网络交互,没有UI
  • b. worker就是用户看到的主要UI
  • c. tools主要包含gallery和webview

拆分网络进程,确实就是为了减少进程回收带来的网络断开。

微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)_0 (4).png 

可以看到push的内存要远远小于worker。而且push的工作性质稳定,内存增长会非常少。这样就可以保证,尽量的减少push 被杀的可能。这里有个思路,但限制比较多,也抛砖引玉。启动一个纯C/C++ 的进程,没有Java run time ,内存使用极低。

这种做法限制很明显,如:没有Java run time ,所以无法使用Android系统接口。缺乏权限,也无法使用各种shell命令操作(如am)。但可以考虑一下用途:高强度运算,网络连接,心跳维持等。比如Shadowsocks-android就如此,通过纯c命令行进程,维护着socks5代理 (Android M运行正常)。

tools进程的拆分也同样是内存的原因:

  • a. 老版本的webview 是有内存泄漏的
  • b. Gallery大量缩略图导致内存使用大

微信在进入后台后,会主动把tools进程kill掉。


进程保活实施:及时拉起


系统回收不可避免,及时重新拉起的手段主要依赖系统特性。从上图看到, push有AlarmReceiver, ConnectReceiver,BootReceiver。这些receiver 都可以在push被杀后,重新拉起。特别AlarmReceiver ,结合心跳逻辑,微信被杀后,重新拉起最多一个心跳周期。

而对于worker,除了用户UI操作启动。在接收消息,或者网络切换等事件, push也会通过LocalBroadcast,重新拉起worker。这种拉起的worker ,大部分初始化已经完成,也能大大提高用户点击微信的启动速度。

历史原因,我们在push和worker通信使用Broadcast和AIDL。实际上,我一直不喜欢这里的实现,AIDL代码冗余多, broadcast效率低。欢迎大家分享更好的思路或者方法。

进程保活实施:进程优先级


Low Memory Killer 决定是否杀进程除了内存大小,还有进程优先级:
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)_0 (5).png 

上表的数字可能在不同系统会有一定的出入,但明确的是,数值越小,优先级越高。对于优先级相同的进程,总是会把内存占用多的先kill。提高进程优先级是保活的最好手段。

正常情况下微信的oom_adj:
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)_0 (6).png 

而被提高优先级后:
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)_0 (7).png 

从统计上报看,提高后的效果极佳。原理:Android 的前台service机制。但该机制的缺陷是通知栏保留了图标。

对于 API level < 18 :调用startForeground(ID, new Notification()),发送空的Notification ,图标则不会显示。对于 API level >= 18:在需要提优先级的service A启动一个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。

这方案实际利用了Android前台service的漏洞。微信在评估了国内不少app已经使用后,才进行了部署。其实目标是让大家站同一起跑线上,哪天google 把漏洞堵了,效果也是一样的。

QA环节


Q:之前看微信的架构分享,貌似是通过单一Activity,用多个Fragment切换来实现的多窗口。如果分进程的话,看起来Gallery和
WebView是单独的一个Activity,我的理解是否正确呢?以及进入后台之后,为何只kill tools而不一起释放work呢?

A: Fragment的改造只是用在有限的几个UI上,大部分的UI,对于切换时间要求不高,还是保留成activity,Gallery和WebView都是单独的
activity,所以才可能另外一个进程的。对于我们来说worker的保活仅次于网络的push,worker如果频繁被杀,用户每次启动微信都需要
等待,这个就不好了。所以,我们在后台,只会kill tools,不会主动kill worker。

Q:除了提高进程的优先级,微信在内存方面有什么处理或优化的技术吗?
A: 不可否认,其实微信是内存大户了,现阶段我们主要关注内存泄漏,没有专门去减少内存的使用,毕竟内存意味着cache,意味着用户体验更快,后续对于内存优化我们有一些规划,比如说,在cache这块照顾一些低端机。

Q:我记得很久以前听说过微信使用一个像素的浮动窗口来保活,不知道现在还有没有呢?
A: 我们有想过,也听说过有其他app是这样做的,但从来没实现过这个方案。

Q:你们push进程与worker进程采用过socket通信方案么?采用的话效果怎么样?
A: 有考虑过用socket,后续也可能会有这种尝试,但因为push和worker依赖代码太多,伤筋动骨了,但估计也要比AIDL好,AIDL对于应用出问题后能做的事情太少了。
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这个错误提示是由于在Vue H5页面分享微信时,分享链接的签名无效导致的。 在微信分享中,需要对分享链接进行签名,以确保链接的完整性和安全性。签名的原理是利用配置的appID、appSecret、noncestr(随机字符串)和timestamp(时间戳)等参数,通过特定的算法生成一个字符串,再将这个字符串进行加密得到签名signature。微信客户端在收到分享链接时,会根据这个签名来验证链接的合法性。 出现"invalid signature"的错误提示,通常是由以下几个原因导致的: 1. 参数配置错误:检查在使用微信分享API时,是否正确配置了appID和appSecret等参数。需要确保这些参数的值是有效的,并且与微信开放平台中的配置一致。 2. 签名生成错误:签名算法可能有误。可以参考微信提供的官方文档,了解签名算法的具体步骤和规则,确保在生成签名时没有遗漏或错误处理相关参数。 3. 随机字符串和时间戳:noncestr和timestamp参数可能未传递或传递错误。在生成签名时,需要使用正确的noncestr和timestamp值。 4. URL编码问题:分享链接中如果包含特殊字符或需要URL编码的字符,需要在生成签名时进行正确的编码处理。 如果还是无法解决该错误,可以尝试在开发者工具中调试,查看具体的错误信息,以便定位问题所在。同时,可以参考微信开放平台的相关文档和社区中的讨论,寻找其他开发者遇到类似问题的解决方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值