Tom*_*cat 47 android kill-process android-source android-wake-lock wakelock
我对wakelock有疑问.在下面显示的情况下,Android操作系统是否释放唤醒锁(PARTIAL_WAKE_LOCK如果您需要指定)以防止获取唤醒锁并且在关闭电源(不睡眠)之前浪费电池.
案例1-a:
App已经在其中一个线程中获得了wakelock(没有超时选项)(在这种情况下请认为这是合理的)并且它被设计为在关键任务完成时释放唤醒锁.应用程序可以被taskmanager或臭名昭着的taskkiller杀死,应用程序没有机会让它的线程释放唤醒锁.那个唤醒锁会发生什么?
案例1-b :(
如果对案例1-a的回答是"是的,请不要担心",那么请忽略这种情况.)与案例1-a相同但应用程序给予唤醒锁的超时选项,比如3秒.此超时选项是否保持有效?
案例2-a:
请想象一下,有一项服务由AlarmManager启动(通过广播接收器),并且该服务已获得唤醒锁(没有超时选项).此服务旨在使唤醒锁获取时间最小化.但不幸的是,由于内存紧缩,Android操作系统选择了这项服务.(我不知道当获得唤醒锁时操作系统是否不会终止服务,但我猜操作系统并不关心.但我希望操作系统稍后会发布唤醒锁.)那个唤醒锁会发生什么?
案例2-b :(
如果对案例2-a的回答是"是的,请不要担心",那么请忽略这种情况.)与案例2-a相同但是服务给了唤醒锁的超时选项,比如3秒.此超时选项是否保持有效?
Sta*_*kER 48
WakeLock实施概述
当我们pm.newWakeLock用来创建一个新的唤醒锁时,PowerManager只需创建一个新的WakeLock对象并返回.WakeLock对象不是绑定对象,因此不能通过多个进程使用它.但是,在该WakeLock对象中,它包含一个名为mToken的Binder对象.
WakeLock(int flags, String tag) {
mFlags = flags;
mTag = tag;
mToken = new Binder();
}
Run Code Online (Sandbox Code Playgroud)
因此,当您在此WakeLock对象上调用获取或释放时,它实际上将该令牌传递给PowerManagerService.
private void acquireLocked() {
if (!mRefCounted || mCount++ == 0) {
mHandler.removeCallbacks(mReleaser);
try {
mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
} catch (RemoteException e) {
}
mHeld = true;
}
}
Run Code Online (Sandbox Code Playgroud)
查看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);
}
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
关键声明是lock.linkToDeath(wakeLock, 0);.这lock正是我们之前提到过的mToken.wakeLock如果此绑定程序消失,此方法会向收件人(the )注册通知.如果此绑定程序对象意外消失(通常是因为其托管进程已被终止),则将binderDied在接收方上调用该方法.
请注意,WakeLock in与WakeLock PowerManagerService不同PowerManager,它是一个实现IBinder.DeathRecipient.所以看看它的binderDied方法.
@Override
public void binderDied() {
PowerManagerService.this.handleWakeLockDeath(this);
}
Run Code Online (Sandbox Code Playgroud)
在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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以我认为在你的问题的两个案例中,答案是不要担心.至少在Android 4.2中(代码来自),这是真的.而且,WakeLock类中有一个finalize方法PowerManager,但这不是你问题的关键.
我会假设(我不确定这一点)Android系统没有为被杀死的进程保留唤醒锁.最有可能当它用sigkill杀死一个进程时,它也会移除该进程所持有的任何唤醒锁.
否则,正如你所说,崩溃将导致手机始终处于清醒状态,这是我没有观察到的.
| 归档时间: |
|
| 查看次数: |
11270 次 |
| 最近记录: |