我有关于觉醒的问题。在下面所示的情况下,android是否会发布唤醒锁(如果需要指定的话)以防止锁锁被保留,并在关闭电源(而不是睡眠)之前浪费电池。
案例1-a:
App已经在它的一个线程中获得了唤醒(w/o超时选项)(请认为在这种情况下它是合理的),它的设计是为了在关键任务完成时释放唤醒。应用程序可以被任务管理器或臭名昭著的任务杀手杀死,而应用程序没有机会让它的线程释放唤醒。那辆警车呢?
判例1-b:
(如果对案例1-a的回答是“是的,别担心”,那么请忽略这个案例。)与案例1一样-a,但应用程序给出超时选项唤醒,比如说3秒。此超时选项有效吗?
案例2-a:
请想象一下,有一个服务是由AlarmManager (通过广播接收器)启动的,并且该服务已经获得了一个觉醒(w/o超时选项)。这项服务的目的是使唤醒时间最短。但不幸的是,由于内存紧张,Android选择了这个服务。(我不知道当买了wakelock的时候OS是否会杀死服务,但我想OS并不在意。但我希望OS稍后会发布wakelock。)那辆警车呢?
案例2-b:
(如果对案例2-a的回答是“是的,别担心”,那么请忽略这个案例。)与案例2-a相同,但是服务给了唤醒的超时选项,比如3秒。此超时选项有效吗?
发布于 2013-04-28 01:28:29
WakeLock实现概述
当我们使用pm.newWakeLock创建一个新的觉醒时,PowerManager只是创建一个新的wakelock对象并返回。WakeLock对象不是绑定对象,因此不能通过多个进程使用它。但是,在这个WakeLock对象中,它包含一个名为mToken的绑定对象。
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)。如果这个绑定器对象意外地消失了(通常是因为它的宿主进程被终止了),那么binderDied方法将在接收者上被调用。
注意,PowerManagerService中的PowerManagerService与PowerManager中的WakeLock不同,它是IBinder.DeathRecipient的实现。因此,请查看它的binderDied方法。
@Override
public void binderDied() {
PowerManagerService.this.handleWakeLockDeath(this);
}handleWakeLockDeath将发布这个唤醒锁。
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();
}
}所以我认为在你的问题中,在这两种情况下,答案都是不用担心。至少在Android4.2(代码来源)中,这是正确的。此外,WakeLock类在PowerManager中有一个finalize方法,但这不是问题的关键。
发布于 2011-04-05 07:54:26
我假设(我不确定这一点) Android系统不会为被杀死的进程保持清醒。最有可能的情况是,当它用sigkill杀死一个进程时,它也会删除该进程所持有的所有唤醒。
否则,就像你说的,撞车会导致电话始终保持清醒,这一点我还没有观察到。
https://stackoverflow.com/questions/4697873
复制相似问题