android android-source wakelock kill-process android-wake-lock

¿Lanza el sistema operativo Android un wakelock si la aplicación o el servicio que lo contiene es asesinado?



android-source kill-process (2)

Supongo (no lo sé con certeza) que el sistema Android no mantiene wakelocks para los procesos eliminados. Lo más probable es que cuando mata un proceso con sigkill, también elimine cualquier wakelocks retenido por ese proceso.

De lo contrario, como dices, los bloqueos conducirían a que el teléfono esté siempre despierto, lo que no he observado.

Tengo una pregunta sobre wakelock. En los casos que se muestran a continuación, ¿el sistema operativo Android libera wakelock ( PARTIAL_WAKE_LOCK si necesita especificarlo) para evitar que se haya adquirido wakelock y gastar batería hasta apagarlo (no dormir).

Caso 1-a:
La aplicación ha adquirido wakelock (sin opción de tiempo de espera) en uno de sus hilos (por favor, piense que es razonable en este caso) y fue diseñada para liberar wakelock cuando finalizó la tarea crítica. La aplicación puede ser eliminada por el taskmanager o el famoso taskkiller, y la aplicación no tiene posibilidad de permitir que su hilo libere wakelock. ¿Qué pasa con ese wakelock?

Caso 1-b:
(Si la respuesta al caso 1-a es "Sí, no se preocupe", ignore este caso). Lo mismo que en el caso 1-a, pero la aplicación dio la opción de tiempo de espera al wakelock, digamos 3 segundos. ¿Esta opción de tiempo de espera se mantiene válida?

Caso 2-a:
Imagina que hay un servicio que inició AlarmManager (a través del receptor Broadcast) y el servicio adquirió un wakelock (opción sin tiempo de espera). Este servicio está diseñado para hacer un mínimo de tiempo adquirido por wakelock. Pero, por desgracia, Android OS eligió este servicio para matar debido a la crisis de memoria. (No sé si OS no matará al servicio cuando se adquiere wakelock, pero supongo que a OS no le importa. Pero espero que OS libere wakelock más tarde). ¿Qué le sucede a ese wakelock?

Caso 2-b:
(Si la respuesta al caso 2-a es "Sí, no se preocupe", ignore este caso). Lo mismo que el caso 2-a pero el servicio dio la opción de tiempo de espera a wakelock, digamos 3 segundos. ¿Esta opción de tiempo de espera se mantiene válida?


Descripción general de la implementación de WakeLock

Cuando usamos pm.newWakeLock para crear un nuevo wakelock, el PowerManager simplemente crea un nuevo objeto WakeLock y lo devuelve. El objeto WakeLock no es un objeto de enlace, por lo que no se puede usar a través de múltiples procesos. Sin embargo, en ese objeto WakeLock, contiene un objeto Binder llamado mToken.

WakeLock(int flags, String tag) { mFlags = flags; mTag = tag; mToken = new Binder(); }

Entonces, cuando llamas a adquirir o liberar en este objeto WakeLock, en realidad pasa ese token a PowerManagerService .

private void acquireLocked() { if (!mRefCounted || mCount++ == 0) { mHandler.removeCallbacks(mReleaser); try { mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource); } catch (RemoteException e) { } mHeld = true; } }

Observe cómo funciona PowerManagerService cuando adquirir o liberar un wakelock lo ayudará a responder su pregunta.

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); } ... } ... }

La declaración clave es lock.linkToDeath(wakeLock, 0); . Esa lock es exactamente la mToken que mencionamos antes. Este método registra al destinatario ( wakeLock ) para una notificación si esta carpeta se va. Si este objeto de enlace desaparece inesperadamente (normalmente porque se ha binderDied su proceso de alojamiento), se binderDied método binderDied en el destinatario.

Tenga en cuenta que WakeLock en PowerManagerService es diferente de WakeLock en PowerManager, es una implementación de IBinder.DeathRecipient . Así que echa un vistazo a su método binderDied .

@Override public void binderDied() { PowerManagerService.this.handleWakeLockDeath(this); }

handleWakeLockDeath liberará ese 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(); } }

Entonces creo que en ambos casos en tu pregunta, la respuesta es no te preocupes. Al menos en Android 4.2 (de donde viene el código), es cierto. Además, hay un método de finalización en la clase WakeLock en PowerManager , pero esta no es la clave de su pregunta.