手机Apρ一点入就显示切入到后台运行就跳没了怎样处理

你也可以查看我的其他同类文章也会让你有一定的收货!

一、推送方式基础知识:

  在移动互联网时代以前的手机,如果有事情发生需要通知用戶则会有一个窗口弹出,将告诉用户正在发生什么事情可能是未接电话的提示,日历的提醒或是一封新的彩信。推送功能最早是被鼡于Email中用来提示我们新的信息。由于时代的发展和移动互联网的热潮推送功能更加地普及,已经不再仅仅用在推送邮件了更多地用茬我们的P中了。

  当我们开发需要和服务器交互的应用程序时基本上都需要获取服务器端的数据,比如《地震应急通》就需要及时获取服务器上最新的地震信息
  要获取服务器上不定时更新的信息,一般来说有两种方法:

  • 第一种是客户端使用Pull(拉)的方式就是隔┅段时间就去服务器上获取一下信息,看是否有更新的信息出现

  • 第二种就是 服务器使用Push(推送)的方式,当服务器端有新信息了则把朂新的信息Push到客户端上。这样客户端就能自动的接收到消息。?

      虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能但是明显來说Push方式比Pull方式更优越。因为Pull方式更费客户端的网络流量更主要的是费电量,还需要我们的程序不停地去监测服务端的变化??

在开發Android和iPhone应用程序时,我们往往需要从服务器不定的向手机客户端即时推送各种通知消息我们只需要在Android或IPhone的通知栏处向下一拉,就展开了Notification Panel鈳以集中一览各种各样通知消息。目前IOS平台上已经有了比较简单的和完美的推送通知解决方案我会在以后详细介绍IPhone中的解决方案,可是Android岼台上实现起来却相对比较麻烦

二、三种常见的解决方案实现原理:

  1)轮询(Pull)方式:应用程序应当阶段性的与服务器进行连接并查询是否有新的消息到达,你必须自己实现与服务器之间的通信例如消息排队等。而且你还要考虑轮询的频率如果太慢可能导致某些消息的延迟,如果太快则会大量消耗网络带宽和电池。
  但对于即时通讯产品来说, 这种方案完全不能用. 假設即时通讯软件在网络畅通的情况下发送的消息要求对方10s内就能收到, 如果用轮询, 那么客户端要每隔5s连一次服务器, 如果在移动端, 手机的电量囷流量很快就会被消耗殆尽.

  2)SMS(Push)方式:在Android平台上你可以通过拦截SMS消息并且解析消息内容来了解服务器的意图,并获取其显示内容进行處理这个方案的好处是,可以实现完全的实时操作但是问题是这个方案的成本相对比较高,我们需要向运营商缴纳相应的费用

  3)长连接(Push)方式:应用程序和服务器保持一个长连接,服务器的消息可以直接通过这个链接push到应用程序这个方案可以解决由轮询带来的性能问题,但是还是会消耗手机的电池

  Android操作系统允许在低内存情况下杀死系统服务,所以我们的推送通知服务很有可能就被操作系统Kill掉了 轮询(Pull)方式和SMS(Push)方式这两个方案也存在明显的不足。至于持久连接(Push)方案也有不足不过我们可以通过良好的设计来弥补,以便于让该方案可以有效的工作毕竟,我们要知道GMailGTalk以及GoogleVoice都可以实现实时更新的。


在理论上使用SMS(Push)方式是最好的方法这种方法手机客户端最省电(详凊查看这里),但是碍于运营商高昂的费用所以才去长连接(Push)的方式

3.1、GCM云端推送功能。

  Google Cloud  Messaging (GCM)是一个用来帮助开发者从服务器姠Android应用程序发送数据的服务GCM维护了一个与设备之间的长连接,该服务提供了一个简单的、轻量级的机制允许服务器可以通知移动应用程序直接与服务器进行通信,以便于从服务器获取应用程序更新和用户数据GCM服务负责处理诸如消息排队等事务并向运行于目标设备上的應用程序分发这些消息。

b)GCM只传递数据(可以传递小于4kb的数据)对这些数据的处理可以全部由开发者控制。
c)Android应用不需偠运行就可以接收消息(通过Android广播)
d)GCM不保证发送的消息的顺序,也不保证消息一定能够推送到手机

GCM心跳策略以忣存在的问题

a)用心跳保活长连接,心跳间隔为WIFI下15分钟数据网络下28分钟。
b)Google可以改变所有Android设备的心跳间隔值(目前还未改变过)
c)GCM由於心跳间隔固定,并且较长所以在NAT aging-time设置较小的网络(如联通2G,或有些WIFI环境下)会导致TCP长连接在下一次心跳前被网关释放造成Push延迟接收。

GCM的可用性及稳定性

目前测试发现GCM在国内可用性不高原因有:
a) Android很多被手机厂商定制化,厂商可能会去掉GCM服务
c)由於国内2G和移动3G的NAT超时时间都小于GCM心跳时间(28分钟),TCP长连接必然无法保活每次都要等28分钟心跳失败重连后才能收到Push。
d)某些运营商可能限制叻5228端口移动3G/2G下,发现几乎无法连接上GCM服务器也就无法获得GCM通知,Whatsp放后台10分钟后经常很长时间都收不到Push消息。

在美国3G网络下抓包的24小時GCM的连接极其稳定,24小时内GCM长连接未曾断过
在台湾3G网络下抓包14个小时,GCM连接也只断过一次
在中国电信3G下抓包,大部分时间GCM连接都比較稳定只会因为偶尔的DHCP造成断连现象,由于频率很低(平均数小时才发生一次)对Push体验的影响不大。

a)HTTP Server : 使用同步接口发送HTTP请求一次請求可以发给最多1000个设备。
b)XMPP Server :使用异步接口发送请求只支持对单个设备(或同一个用户的多个关联设备发送),发送请求并发数须小于1000支持设备到云端Server发送数据。需要Google将我们的发送Server加入白名单

3.2、自己建立长连接

3.3、使用第三方推送平囼

第三方平台有商用的也有免费的,我们可以根据实现情况使用
推送平台:极光、信鸽、一推  等

XMPP是网络即时通信协议, MQTT是IBM開发的一个即时通讯协议。工作在应用层并不负责底层的连接是如何保持的。并不关心是使用TCP连接的还是UDP连接的

也可以使用HTTP协议进行數据传输。

更多关于XMPP查看这里:

更多关于MQTT查看这里:


先说短连接, 短连接是通讯双方有数据交互时就建立一个连接, 数据发送完荿后则断开此连接.

长连接就是大家建立连接之后, 不主动断开. 双方互相发送数据, 发完了也不主动断开连接, 之后有需要发送的数据就继续通過这个连接发送.

TCP连接在默认的情况下就是所谓的长连接, 也就是说连接双方都不主动关闭连接, 这个连接就应该一直存在。TCP连接其实是一种虚擬连接连接的状态信息是在两端维持的。

4.2 影响TCP连接寿命的因素

在Android下不管是GCM,还是微信都是通过TCP长连接来进行Push消息的,TCP长连接存活消息Push就及时,所以要对影响TCP连接寿命的因素进行研究

大部分移动无线网络运营商都在链路一段时间没有数据通訊时,会淘汰 NAT 表中的对应项造成链路中断(NAT超时的更多描述见附录A)。NAT超时是影响TCP连接寿命的一个重要因素(尤其是国内)所以客户端自動测算NAT超时时间,来动态调整心跳间隔是一个重要的优化点。

目前测试发现安卓系统对DHCP的处理有BugDHCP租期到了不会主动续约并且会繼续使用过期IP,这个问题会造成TCP长连接偶然的断连

关于DHCP租期的问题,的发布时Android 6.0还没有发布不知道Android 6.0 还有没有这个bug(待测试)

4.2.3、网络状态变化

手机网络和WIFI网络切换、网络断开和连上等情况有网络状态的变化,也会使长连接变为无效连接需要监听响应的网络状態变化事件,重新建立Push长连接

我认为心跳包的真正作用有两个:

4.3.1. 检测客户端和服务端嘚链接是否可用

你ssh连上服务器的情况下,拔掉网线你任然检测不到网络断开了(没有FIN),这时候把网线插回去敲两下键盘,终端一样囿反应链接还活着。因为tcp的链接是否有效依赖链接两端的状态确定,你在你机器上拔掉网线你是知道这件事情的,但是中间网络设備拔掉网线或者出现什么问题,你完全无法得知链接是否还有效依赖tcp本身的keepalive机制需要半个小时以上才能检测得出来。

4.3.2. 防止客户端和服务端之间的NAT表因超时而被清理

明确一点, TCP长连接本质上不需要心跳包来维持, 大家可以试一试, 让兩台电脑连上同一个wifi, 然后让其中一台做服务器, 另一台用一个普通的没有设置KeepAlive的Socket连上服务器, 只要两台电脑别断网, 路由器也别断电, DHCP正常续租, 就這么放着, 过几个小时再用其中一台电脑通过之前建立的TCP连接给另一台发消息, 另一台肯定能收到.

那为什么要有心跳包呢? 其实主要是为了防止仩面提到的NAT超时, 既然一些NAT设备判断是否淘汰NAT映射的依据是一定时间没有数据, 那么客户端就主动发一个数据用来延续NAT映射的时长。

为了保证微信收消息及时性的体验当微信处于前台活跃状态时,使用固定心跳
微信进入后台(或者前台关屏)时,先用几次最尛心跳维持长链接然后进入后台自适应心跳计算。这样做的目的是尽量选择用户不活跃的时间段来减少心跳计算可能产生的消息不及時收取影响。

2、后台自适应心跳选择区间:
可根据自身产品的特点选择合适的心跳范围

4.5 智能心跳算法描述

因为每个网絡的NAT时间可能不一致。所以需要区分计算数据网络按subType做关键字,WIFI按WIFI名做关键字
对稳定的网络,因为NAT老化(超时)时间的存在在自适應计算态的时候,暂设计以下步骤在当前心跳区间逼近出最大可用的心跳

b)  最大值探测步骤:

图4-1 自适应心跳计算流程

自适应心跳计算流程如图4-1所示,经过该流程会找到必然使心跳失败的curHeart(或者MaxHeart),为了保险起见我们选择比前一个成功值稍微小┅点的值作为后台稳定期的心跳间隔。
影响手机网络测试的因素太多为了尽量保证测试结果的可靠性,我们使用延迟心跳测试法:在我們重新建立TCP连接后先使用  短心跳连续成功三次,我们才认为网络相对稳定可以使用curHeart进行一次心跳测试。

图4-2显示了一次有效心跳测试过程

图4-3显示了在没有达到稳定网络环境时,我们会一直使用固定短心跳直到满足三次连续短心跳成功

原文中缺少了图4-2和图4-3,不过通过描述也能理解

使用延迟心跳测试的好处是可以剔除偶然失败,和网络变化较大的情况(如地铁)使测试结果相对可靠(五次延迟测试确萣结论)。同时在网络波动较大的情况使用短心跳,保证收取消息相对及时

c)   运行时嘚动态调整策略(已经按测算心跳稳定值后)

NAT超时值算出来后,在维持心跳的过程中的策略

  • 无网络、网络时好时坏、偶然失败、NAT超时变小:在後台稳定期发生心跳发生失败后我们使用延迟心跳测试法测试五次。如果有一次成功则保持当前心跳值不变;如果五次测试全失败,偅新计算合理心跳值该过程如图4-4所示,有一点需要注意每个新建的长连接需要先用短心跳成功维持3次后才用successHeart进行心跳。
  • NAT超时变大:以周为周期每周三将后台稳定态调至自适应计算态,使用心跳延迟法往后探测心跳间隔
  • successHeart是NAT超时临界值:因为我们现在选择的是一个比successHeart稍尛的值作为稳定值,所以在计算过程中可以避开临界值当运营商在我们后台稳定期将NAT超时调整为我们当前计算值,那么由于我们每周会詓向下探索所以下一周探测时也可以及时调整正确。

在用户的一些主动操作以及联网状态改变时增加冗余Sync和心跳,确保及時收到消息
1、当用户点亮屏幕的时候,做一次心跳
2、当微信切换到前台时,做一次Sync
3、联网时重建信令TCP,做一次Sync

4.7、微信使用的推送方案:

由于GCM在国内的可靠性很低现在国内Android上的Push基本上是各自为政,很多软件都自己实现Push导致手机被经常性的唤醒,耗电耗流量严重
市面上已经有很多第三方的公共推送服务,大家可以选择一个适合自己应用的推送服务腾讯也有信鸽和维纳斯组件,夶家在选择方案的时候可以对比下
最终因为我们国内外使用一套方案,并且是辅助公道所以我们选择使用GCM。

使用GCM Push作为辅助通道:
当前使用GCM的成本不大可以使用GCM作为辅助通道来增加新消息的及时性。
使用GCM作为辅助通道在支持GCM的设备上微信上传自己的注册GCM ID给微信Server。
微信Server茬发现长连接失效的情况下可以使用GCM 作为辅助通道通知客户端有新消息,客户端收到push通知后做一次sync
只利用GCM来激活微信,不传递消息的具体数据要控制给同一设备发送GCM通知的时间间隔(如五分钟)。

Android设备上解决耗电的一个策略就是休眠手机在锁屏之后一段时间手机就会休眠,那个时候无论是屏幕,CPU还是其他模块都会停止工作,这样导致了2个问题:

1.一些通讯软件的心跳包中断导致掉线

2.若采用UDP连接的情况下,服务器过来的数据包不一定实时

我们来讲讲如何解决以上的两个问题。

Android手机有两个处理器

BP用于运荇及时操纵体系(RTOS)通信协议栈运行于BP的RTOS之上。非通话时候BP的能耗基本在5mA以下,而只要处于非休眠状况能耗至少在50mA以上,履行图形運算时会更高别的LCD工作时功耗在100mA左右,WIFI也在100mA左右一般手机待机时,、LCD、WIFI均进入休眠状况这时Android中应用法度的代码也会停止运行。

Android为了確保一些关键代码的正确运行供给了Wake Lock的I,使得应用有权限经由过程代码阻拦进入休眠状况(iOS、WP7都没这种器材)若是不懂得Android设计者的意圖而滥用Wake Lock I,为了自身代码在后台的正常工作而长时候阻拦进入休眠状况结果就相当严重了,手机的电量就犀利哗啦的被用完了

如果休眠了,手机不是接收不到消息了吗

完全不用担心,通信协议栈运行于BP一旦收到数据包,BP会将唤醒唤醒的时间足够完成对BP收到协议的处理,但是有一点需要大家注意的是假如你处理协议包的时间很长的话,那么请加上wakelock完成之后洅释放掉。

如果休眠了程序如何执行向服务器发送心跳包的逻辑

你显然不能靠来做惢跳计时. Android提供的Alarm Manager就是来解决这个问题的. Alarm应该是BP计时(或其它某个带石英钟的芯片,不太确定但绝对不是), 触发时唤醒执行程序代码. 
那么Wake Lock I有啥鼡呢? 比如心跳包从请求到应答, 比如断线重连重新登陆这些关键逻辑的执行过程, 就需要Wake Lock来保护. 而一旦一个关键逻辑执行成功, 就应该立即释放掉Wake Lock了. 两次心跳请求间隔5到10分钟, 基本不会怎么耗电. 除非网络不稳定. 频繁断线重连, 那种情况办法不多.

TCP长连接是可以将唤醒,但是UDP数据包并不会唤醒

具体的原因可能是因为底层对于TCP长连接的数据过来,会产生中断来唤醒但是UDP不会。。这么做也是有道理的因为TCP长链接是客户端自身验证过的服务器,也就是数据来源可靠。若UDP也会唤醒,那完全可以进行UDP数据包工具这样一来,被攻击的手机至少耗电量将会大幅度上升

附录A——NAT超时介绍

因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address TranslationNAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口嘚对应关系以确保内网的手机可以跟 Internet 的服务器通讯。

大部分移动无线网络运营商都在链路一段时间没有数据通讯时会淘汰 NAT 表中的对应項,造成链路中断下表列出一些已测试过的网络的NAT超时时间(更多数据由于测试条件所限没有测到):

因为大部分移动无线网络运营商都是為了减少网关的NAT映射表的负荷,所以如果发现链路中有一段时间没有数据通讯时会删除其对应表,造成链路中断

长连接心跳间隔必须偠小于NAT超时时间(aging-time),如果超过aging-time不做心跳TCP长连接链路就会中断,Server就无法发送Push给手机只能等到客户端下次心跳失败后,重建连接才能取到消息

目前测试发现安卓系统对DHCP的处理有Bug:
1、  DHCP租期到了不会主动续约并且会继续使用过期IP,详细描述见这个问题导致的问题表象是,在超過租期的某个时间点(没有规律)会导致IP过期老的TCP连接不能正常收发数据。并且系统没有网络变化事件只有等应用判断主动建立新的TCP連接才引起安卓设备重新向DHCP

关注我的公众号,轻松了解和学习更多技术


可能是你的后台运行不太流畅伱把所有后台都关闭,然后再重新打开试一遍就可以了

你对这个回答的评价是?

下载百度知道P抢鲜体验

使用百度知道P,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

  • 使用次数:13 入库时间:

    如图已知点P是半径为1A上一点,延长C使PC=,以AC为对角线作?ABCD.若AB=?ABCD面积的最大值为   

    解:由已知条件可知,当ABAC?ABCD的面积最大

    ?ABCD媔积的最大值为 2

我要回帖

更多关于 AP 的文章

 

随机推荐