Ответ 1
Обзор реализации WakeLock
Когда мы используем pm.newWakeLock
для создания нового wakelock, PowerManager
просто создает новый объект WakeLock и возвращается. Объект WakeLock не является связующим объектом, поэтому он не может использоваться несколькими процессами. Однако в этом объекте WakeLock он содержит объект Binder с именем 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
, когда вы приобретаете или выпускаете wakelock, чтобы помочь вам ответить на ваш вопрос.
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
получит вызов получателя.
Обратите внимание, что WakeLock в PowerManagerService
отличается от WakeLock в PowerManager
, это реализация 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();
}
}
Поэтому я думаю, что в обоих случаях в вашем вопросе ответ не волнуется. По крайней мере, в Android 4.2 (откуда приходит код) это правда. Кроме того, существует метод finalize для класса WakeLock в PowerManager
, но это не является ключом к вашему вопросу.