android 后台锁屏时候不应该继续执行操作

Android是一个相当开放的平台,允许我们开发常驻后台运行的应用程序,依靠TCP长连接接受服务器的消息推送,但也因此在电量消耗方面广遭诟病。如果开发者,特别是类IM应用的开发者自己还不去了解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进入休眠状态(iOS、WP7都没这种东西)。如果不领会Android设计者的意图而滥用Wake Lock API,为了自身程序在后台的正常工作而长时间阻止AP进入休眠状态,后果就相当严重了。

首先,完全没必要担心AP休眠会导致收不到消息推送。通讯协议栈运行于BP,一旦收到数据包,BP会将AP唤醒,唤醒的时间足够AP执行代码完成对收到的数据包的处理过程。其它的如Connectivity事件触发时AP同样会被唤醒。那么唯一的问题就是程序如何执行向服务器发送心跳包的逻辑。你显然不能靠AP来做心跳计时。Android提供的Alarm Manager就是来解决这个问题的。Alarm运行在BP上,触发时唤醒AP执行程序代码。那么Wake Lock API有啥用呢?比如心跳包从请求到应答,比如断线重连时验证密码这些关键逻辑的执行过程,就需要Wake Lock来保护。而一旦一个关键逻辑执行成功,应该立即释放掉Wake Lock了。心跳间隔也不宜过短,至少隔个10分钟吧。

服务器端也不要有事没事都向客户端推送TCP包。客户端后台运行时,最好只在必须要客户端立即在状态栏显示内容时推送一个包,别的数据都得缓存起来,等待客户端进入前台运行时主动请求,或者也可以加在心跳请求的应答中带给客户端。因为每推送一次,客户端都得唤醒AP处理这个推送。这个说起来容易,但作为一个后台TCP长链接的应用,服务端很可能会在一些逻辑的设计上图省事而抑制不住立即向客户端推送的冲动。

Android锁屏无法继续定位问题 产生问题的原因: 手机锁屏后,Android系统为了省电以及减少CPU消耗,在一段时间后会将手机进入休眠状态。此时的服务以及线程等都会停止。 最近就这个问题,阅读了很多代码以及官方文档,下面就说下最近都尝试过的方式,可能其中有些您实现了,我这边没实现,望见谅。本文采用的高德定位。 一、PowerManager.WakeLock (1)直接强制当前页面cpu运行 private PowerManager pm; private PowerManager.WakeLock wakeLock; @Override public void onCreate() { super.onCreate(); //创建PowerManager对象 pm = (PowerManager) getSystemService(Context.POWER_SERVICE); //保持cpu一直运行,不管屏幕是否黑屏 wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "CPUKeepRunning"); wakeLock.acquire(); } @Override public void onDestroy() { wakeLock.release(); super.onDestroy(); } 这个写法我表示并没有什么用,并不能强制cpu持续运行。 (2)WakefulBroadcastReceiver public class WLWakefulReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // String extra = intent.getStringExtra("msg"); Intent serviceIntent = new Intent(context, MyIntentService.class); serviceIntent.putExtra("msg", extra); startWakefulService(context, serviceIntent); } } WakefulBroadcastReceiver 内部的原理也是PowerManager,注册广播时8.0的请动态注册,静态没有用。广播注册完了之后,写一个服务用来与广播互动。 public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override public void onCreate() { super.onCreate(); } @Override protected void onHandleIntent(@Nullable final Intent intent) { //子线程中执行 Log.i("MyIntentService", "onHandleIntent"); String extra = intent.getStringExtra("msg"); new Thread(new Runnable() { @Override public void run() { LocationUtil.getInstance().startLocation(LocationUtil.NULL, new LocationUtil.OnLocationBack() { @Override public void back(AMapLocation aMapLocation, String backString) { Log.e("定位結果", aMapLocation.getAddress()+""); 定位结果操作,我这边是把定位的时候保存到数据库里面。 } }); } }).start(); Log.i("MyIntentService", "onHandleIntent:"+extra); //调用completeWakefulIntent来释放唤醒锁。 // WLWakefulReceiver.completeWakefulIntent(intent); } } 注册
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值