android心跳包
㈠ android 如何使用Wake Lock来节电
android 使用Wake Lock来节电方法:
默认情况下,Android设备会在一段时间后使屏幕变暗,然后关闭屏幕显示,最后停止CPU,有时用户并不希望如此,因此Android提供了WakeLock类让用户实现自定义的电源管理,但是如果不合理使用这个功能,应用程序造成的电池电量消耗产生显着的影响,所以建议当用户观看屏幕但是很少与屏幕进行交互时(如看视频)使用,从而防止屏幕变暗。
如果一开始就对Android手机的硬件架构有一定的了解,设计出的应用程序通常不会成为待机电池杀手,而要设计出正确的通信机制与通信协议也并不困难。但如果不去了解而盲目设计,可就没准了。
首先Android手机有两个处理器,一个叫Application Processor(AP),一个叫Baseband Processor(BP)。AP是ARM架构的处理器,用于运行Linux+Android系统;BP用于运行实时操作系统(RTOS),通讯协议栈运行于BP的RTOS之上。非通话时间,BP的能耗基本上在5mA左右,而AP只要处于非休眠状态,能耗至少在50mA以上,执行图形运算时会更高。另外LCD工作时功耗在100mA左右,WIFI也在100mA左右。一般手机待机时,AP、LCD、WIFI均进入休眠状态,这时Android中应用程序的代码也会停止执行。
Android为了确保应用程序中关键代码的正确执行,提供了Wake Lock的API,使得应用程序有权限通过代码阻止AP进入休眠状态。但如果不领会Android设计者的意图而滥用Wake Lock API,为了自身程序在后台的正常工作而长时间阻止AP进入休眠状态,就会成为待机电池杀手。比如前段时间的某应用,比如现在仍然干着这事的某应用。
㈡ 如何避免拖延Android的GCM消息/更改心跳
关于这个问题,我做个gcm,如果不对于心跳包进行实际间隔的更改,延迟会比较严重,可以参考一下我的csdn的博客:你好邱林和,里面有一篇文章讲到了。
㈢ 什么是心跳包!
一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。基本原因是服务器端不能有效的判断客户端是否在线也就是说,服务器无法区分客户端是长时间在空闲,还是已经掉线的情况.所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。一般来说,出于效率的考虑,是由客户端主动向服务器端发包,而不是
就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包。
就是定时发送给对方一个数据包,告诉对方自己还在维护对话,同时获得返回的数据,判断对方是否在会话中。
客户端每隔一段时间发一个包,使用TCP的,用send发,使用UDP的,用sendto发,服务器收到后,就知道当前客户端还处于“活着”的状态,否则,如果隔一定时间未收到这样的包,则服务器认为客户端已经断开,进行相应的客户端断开逻辑处理。
㈣ 请问如何在android下计算出心跳包的发送频率
[图文]2013年2月2日 - //向服务器发送心跳包 sendHeartbeatPackage(...点击复制链接 与好友分享!回本站首页 分享到:...java程序移植到android上问题解决小结Android入门第...
㈤ android 心跳包服务器怎么写
[java]
{
privateThreadmThread;
publicintcount=0;
privatebooleanisTip=true;
privatestaticStringmRestMsg;
privatestaticStringKEY_REST_MSG="KEY_REST_MSG";
@Override
publicvoidrun()
{
while(true)
{
try
{
if(count>1)
{
Log.i("@qi","offline");
count=1;
if(isTip)
{
//判断应用是否在运行
ActivityManageram=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo>list=am.getRunningTasks(3);
for(RunningTaskInfoinfo:list)
{
if(info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知应用,显示提示“连接不到服务器”
Intentintent=newIntent("org.yhn.demo");
intent.putExtra("msg",true);
sendBroadcast(intent);
break;
}
}
isTip=false;
}
}
if(mRestMsg!=""&&mRestMsg!=null)
{
//向服务器发送心跳包
sendHeartbeatPackage(mRestMsg);
count+=1;
}
Thread.sleep(1000*3);
}
catch(InterruptedExceptione)
{
e.printStackTrace();
}
}
}
(Stringmsg)
{
HttpGethttpGet=newHttpGet(msg);
DefaultHttpClienthttpClient=newDefaultHttpClient();
//发送请求
HttpResponsehttpResponse=null;
try
{
httpResponse=httpClient.execute(httpGet);
}
catch(Exceptione)
{
e.printStackTrace();
}
if(httpResponse==null)
{
return;
}
//处理返回结果
finalintresponseCode=httpResponse.getStatusLine().getStatusCode();
if(responseCode==HttpStatus.SC_OK)
{
//只要服务器有回应就OK
count=0;
isTip=true;
}
else
{
Log.i("@qi","responseCode"+responseCode);
}
}
@Override
publicIBinderonBind(Intentintent)
{
returnnull;
}
@Override
publicvoidonCreate()
{
super.onCreate();
}@Override
publicvoidonDestroy()
{
super.onDestroy();
}
publicvoidonStart(Intentintent,intstartId)
{
Log.i("@qi","serviceonStart");
//从本地读取服务器的URL,如果没有就用传进来的URL
mRestMsg=getRestMsg();
if(mRestMsg==null||mRestMsg=="")
{
mRestMsg=intent.getExtras().getString("url");
}
setRestMsg(mRestMsg);
mThread=newThread(this);
mThread.start();
count=0;
super.onStart(intent,startId);
}
publicStringgetRestMsg()
{
SharedPreferencesprefer=getSharedPreferences("settings.data",Context.MODE_PRIVATE);
Log.i("@qi","getRestMsg()"+prefer.getString(KEY_REST_MSG,""));
returnprefer.getString(KEY_REST_MSG,"");
}
publicvoidsetRestMsg(StringrestMsg)
{
SharedPreferencesprefer=getSharedPreferences("settings.data",Context.MODE_PRIVATE);
SharedPreferences.Editoreditor=prefer.edit();
editor.putString(KEY_REST_MSG,restMsg);
editor.commit();
}
}
{
privateThreadmThread;
publicintcount=0;
privatebooleanisTip=true;
privatestaticStringmRestMsg;
privatestaticStringKEY_REST_MSG="KEY_REST_MSG";
@Override
publicvoidrun()
{
while(true)
{
try
{
if(count>1)
{
Log.i("@qi","offline");
count=1;
if(isTip)
{
//判断应用是否在运行
ActivityManageram=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo>list=am.getRunningTasks(3);
for(RunningTaskInfoinfo:list)
{
if(info.topActivity.getPackageName().equals("org.yhn.demo"))
{
//通知应用,显示提示“连接不到服务器”
Intentintent=newIntent("org.yhn.demo");
intent.putExtra("msg",true);
sendBroadcast(intent);
break;
}
}
isTip=false;
}
}
if(mRestMsg!=""&&mRestMsg!=null)
{
//向服务器发送心跳包
sendHeartbeatPackage(mRestMsg);
count+=1;
}
Thread.sleep(1000*3);
}
catch(InterruptedExceptione)
{
e.printStackTrace();
}
}
}
(Stringmsg)
{
HttpGethttpGet=newHttpGet(msg);
DefaultHttpClienthttpClient=newDefaultHttpClient();
//发送请求
HttpResponsehttpResponse=null;
try
{
httpResponse=httpClient.execute(httpGet);
}
catch(Exceptione)
{
e.printStackTrace();
}
if(httpResponse==null)
{
return;
}
//处理返回结果
finalintresponseCode=httpResponse.getStatusLine().getStatusCode();
if(responseCode==HttpStatus.SC_OK)
{
//只要服务器有回应就OK
count=0;
isTip=true;
}
else
{
Log.i("@qi","responseCode"+responseCode);
}
}
@Override
publicIBinderonBind(Intentintent)
{
returnnull;
}
@Override
publicvoidonCreate()
{
super.onCreate();
}@Override
publicvoidonDestroy()
{
super.onDestroy();
}
publicvoidonStart(Intentintent,intstartId)
{
Log.i("@qi","serviceonStart");
//从本地读取服务器的URL,如果没有就用传进来的URL
mRestMsg=getRestMsg();
if(mRestMsg==null||mRestMsg=="")
{
mRestMsg=intent.getExtras().getString("url");
}
setRestMsg(mRestMsg);
mThread=newThread(this);
mThread.start();
count=0;
super.onStart(intent,startId);
}
publicStringgetRestMsg()
{
SharedPreferencesprefer=getSharedPreferences("settings.data",Context.MODE_PRIVATE);
Log.i("@qi","getRestMsg()"+prefer.getString(KEY_REST_MSG,""));
returnprefer.getString(KEY_REST_MSG,"");
}
publicvoidsetRestMsg(StringrestMsg)
{
SharedPreferencesprefer=getSharedPreferences("settings.data",Context.MODE_PRIVATE);
SharedPreferences.Editoreditor=prefer.edit();
editor.putString(KEY_REST_MSG,restMsg);
editor.commit();
}
}
启动Service:
[java]
IntentserviceIntent=newIntent("HeartbeatService");
serviceIntent.putExtra("url",url);
startService(serviceIntent);
IntentserviceIntent=newIntent("HeartbeatService");
serviceIntent.putExtra("url",url);
startService(serviceIntent);
最后别忘了注册Server和GET_TASKS
[html]
<service
android:name=".demo.HeartbeatService"
android:label="QServer"
android:persistent="true">
<intent-filter>
<actionandroid:name="HeartbeatService"/>
</intent-filter>
</service>
<service
android:name=".demo.HeartbeatService"
android:label="QServer"
android:persistent="true">
<intent-filter>
<actionandroid:name="HeartbeatService"/>
</intent-filter>
</service>[html]viewplainprint?
<uses-permissionandroid:name="android.permission.GET_TASKS"/>
<uses-permissionandroid:name="android.permission.GET_TASKS"/>
㈥ Android推送中心跳和轮询的区别
轮询耗费性能,因为每次轮询都要经过一次TCP的连接和断开。
轮询是为了获取数据,而心跳包是为了保活TCP连接,防止NAT超时(内网和外网的映射表)
轮询设定的时间大小决定了数据获取的及时性,心跳包的发送时间间隔和数据的及时性没有太大的关系,如果心跳包发送的时间间隔大于NAT淘汰的时间会导致长连接断开。
㈦ android手机连接无线模块几小时后发生Software caused connection abort异常 导致连接被拒绝 怎么解决
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
发生这个异常,从异常提示看是由于程序引起的,而非网络方面的原因,引发该异常的
场景之一:
客户机<-->服务器,之间是由一个socket 长连接来通信,客户端有一个接收线程在while(true){..}循环里不停地从InputStream流中读数据,客户机每隔几秒钟发一次心跳包至服务端,如果连续未收到心跳包响应的次数已达到规定的次数,客户机认为此链路异常,将socket关闭,那么服务器会抛出java.net.SocketException: Connection reset by peer异常,然后分配给此socket连接的线程退出,那么客户端在while(true){..}循环,读取流时便会发java.net.SocketException:Software caused connection abort: recv failed异常。
已知会导致这种异常的一个场景如下:
客户端和服务端建立tcp的短连接,每次客户端发送一次请求,
服务端响应后关闭与客户端的连接.
如果客户端在服务端关闭连接后,没有释放连接,继续试图发送请求和接收响应.
这个时候就会出错.
这个时候客户端Socket的getOutputStream返回来的OutPutStream维护
的是本地的连接状态,
无法知道远程的服务端已经关闭了对应的InputStream和socket因此
虽然调用了
out.write(sendbuf, 0, sendbuf.length);
方法,但是实际上服务端并没有接收到客户端的请求信息.
因为没有抛出异常,因此造成了误以为客户端请求发送成功的假象.
接下来调用etInputStream的in.read(header, 0, 14);方法.
因为这次要读取服务端的信息,因此产生了
Software caused connection abort: recv failed的异常
总结产生原因,在服务端/客户端单方面关闭连接的情况下,另一方依然以为
tcp连接仍然建立,试图读取对方的响应数据,导致出现
Software caused connection abort: recv failed的异常.
因此在receive数据之前,要先判断连接状态.
通过inputstream的available()方法来判断,是否有响应结果.
如果available()的返回值为0,说明没有响应数据,可能是对方已经断开连接,
如果available()的返回值大于0,说明有响应数据.
另外值得注意的是available()返回的值是非堵塞的,可以被多个线程访问
在对方释放连接后,也要释放本地的连接.
㈧ android 消息推送是什么,消息推送一般是怎么做的
是从服务器不定的向手机客户端即时推送各种通知消息。消息推送方法是:1、可以通过SMS进行服务器端和客户端的交流通信。 可以通过拦截SMS消息并且解析消息内容来了解服务器的意图,可以实现完全的实时操作。
3、循环主动定时获取
这种方法是需要客户端来做一个定时或者周期性的访问服务器端接口,来获得最新的消息。
3、持久连接
这个方案虽然可以解决由轮询带来的性能问题等各种问题,但是还是会消耗手机的电池。
消息推送可以选择深圳极光,是一个不错的软件;也是是国内领先的移动开发者服务提供商。极光通过该一体化消息下发平台,助力行业客户实现多通道高效精准触达目标用户。截至2021年3月,已有超173.1万款APP在使用极光提供的服务。
㈨ android6.0 微信心跳包多久一次
在支持GCM的设备上,主要靠GCM来激活WhatsApp,WhatsApp启动后,会建立一个与服务器的长连接,直接通过此长连接发送Push消息,这个长连接10分钟无消息就会主动断掉,且这十分钟内不做心跳,断掉后WhatsApp客户端和它的服务器不再有连接。当有消息时候,服务器发现没有长连接会发送GCM消息,手机收到GCM消息后,会重新建立长连接来收取消息,10分钟无消息会再断开,如此循环。
㈩ android socket tcp 为什么要发送心跳包
后台开启一个线程一直运行,每隔1分钟左右发送一个心跳报文给服务器,以确保时刻跟服务器链接。若超过3次服务器未对客户端发送的心跳报文做出回应则重新链接。 如果这么作的话,必须确保和服务器达成一定的应用层协议。