如果持有它的应用程序或服务被杀死,Android操作系统是否会释放唤醒锁?
我有关于唤醒的问题。 在下面显示的情况下,android操作系统是否会释放唤醒锁( PARTIAL_WAKE_LOCK
如果您需要指定的话),以防止唤醒锁被遗弃并浪费电池直到closures电源(不睡眠)。
案例1-a:
应用程序已经在它的一个线程中获得了wakelock(w / o timeout选项)(在这种情况下请认为是合理的),并且在关键任务完成时它被devise为释放唤醒锁。 应用程序可以被任务pipe理器或臭名昭着的taskkiller杀死,应用程序没有机会让其线程释放wakelock。 那个wakelock发生了什么事?
案例1-b:
(如果对案例1-a的回答是“是的,别担心”,那么请忽略这种情况)。与案例1-a相同,但是应用程序给了唤醒锁的超时选项,比如说3秒。 这个超时选项是否保持有效?
案例2-a:
请想象有一个由AlarmManager(通过广播接收器)启动的服务,并且该服务已经获得唤醒锁(不带超时选项)。 这项服务的目的是使获得时间最less。 但不幸的是,由于内存紧缩,Android操作系统select了这个服务来杀死。 (我不知道操作系统在获取wakelock的时候是不是会杀了服务器,但是我猜操作系统并不在意,但是我希望操作系统稍后会释放wakelock。)那个wakelock会发生什么?
案例2-b:
(如果对案例2-a的回答是“是,别担心”,那么请忽略这种情况。)与情况2-a相同,但是服务给予唤醒锁的超时选项,例如3秒。 这个超时选项是否保持有效?
WakeLock实现概述
当我们使用pm.newWakeLock
创build一个新的唤醒锁时, PowerManager
只是创build一个新的WakeLock对象并返回。 WakeLock对象不是一个活页夹对象,所以不能通过多个进程使用。 但是,在那个WakeLock对象中,它包含一个名为mToken的Binder对象。
WakeLock(int flags, String tag) { mFlags = flags; mTag = tag; mToken = new Binder(); }
所以当你调用这个WakeLock对象的获取或释放时,它实际上将该令牌传递给PowerManagerService
。
private void acquireLocked() { if (!mRefCounted || mCount++ == 0) { mHandler.removeCallbacks(mReleaser); try { mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); } catch (RemoteException e) { } mHeld = true; } }
看看PowerManagerService
如何在获取或释放唤醒锁时帮助您回答您的问题。
void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws, int uid, int pid) { synchronized (mLock) { ... WakeLock wakeLock; int index = findWakeLockIndexLocked(lock); if (index >= 0) { ... // Update existing wake lock. This shouldn't happen but is harmless. ... } else { wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid); try { lock.linkToDeath(wakeLock, 0); } catch (RemoteException ex) { throw new IllegalArgumentException("Wake lock is already dead."); } notifyWakeLockAcquiredLocked(wakeLock); mWakeLocks.add(wakeLock); } ... } ... }
关键语句是lock.linkToDeath(wakeLock, 0);
。 这个lock
正是我们之前提到的mToken。 如果此联编程序消失,此方法wakeLock
收件人( wakeLock
)注册为通知。 如果这个binder对象意外消失(通常是因为它的宿主进程已被binderDied
),那么将在接收者上调用binderDied
方法。
请注意, PowerManagerService
中的WakeLock与PowerManagerService
中的WakeLock不同,它是IBinder.DeathRecipient
的实现。 所以看看它的binderDied
方法。
@Override public void binderDied() { PowerManagerService.this.handleWakeLockDeath(this); }
handleWakeLockDeath
将释放该wakelock。
private void handleWakeLockDeath(WakeLock wakeLock) { synchronized (mLock) { ... int index = mWakeLocks.indexOf(wakeLock); if (index < 0) { return; } mWakeLocks.remove(index); notifyWakeLockReleasedLocked(wakeLock); applyWakeLockFlagsOnReleaseLocked(wakeLock); mDirty |= DIRTY_WAKE_LOCKS; updatePowerStateLocked(); } }
所以我觉得在这两个问题上你的问题,答案是不要担心。 至less在Android 4.2(代码来自哪里),这是真的。 而且, PowerManager
的WakeLock类有一个finalize方法,但这不是问题的关键。
我会假设(我不知道这是肯定的)Android系统不保留wakelocks死亡进程。 最有可能的是,当它用sigkill杀死一个进程时,它也会去除该进程中的任何唤醒锁。
否则,如你所说,崩溃会导致电话总是清醒,我没有注意到。