难道Android操作系统发布wakelock如果应用程序或服务抱着它被杀死?

问题描述:

我有关于wakelock问题。在下面显示的情况下,做Android操作系统版本wakelock( PARTIAL_WAKE_LOCK 如果你需要指定),以prevent wakelock留下采集和浪费电池,直到关闭电​​源(不睡觉)。

I have question about wakelock. In cases shown below, does android OS release wakelock (PARTIAL_WAKE_LOCK if you need to specify) to prevent wakelock was left acquired and wasting battery until turning power off (not sleep).

案例1-A:
应用程序已经收购wakelock(W / O超时选项),在它的一个线程(请想在这种情况下是合理的),它在设计时,关键的任务已经完成,释放wakelock。应用程序可以通过任务管理器或臭名昭著的taskkiller被杀,应用程序有没有机会让其线程释放wakelock。发生于wakelock什么?

Case 1-a:
App has acquired wakelock (w/o timeout option) in one of its threads (please think it is reasonable in this case) and it was designed to release wakelock when critical task was finished. App can be killed by taskmanager or notorious taskkiller, and app has no chance to let its thread release wakelock. What happens to that wakelock?

案例1-B:
(如果回答情况1,一个是是的,别担心,那么请忽略这种情况。) 同案例1-A,但应用了超时选项wakelock,说3秒。难道这超时选项保持有效?

Case 1-b:
(If answer to case 1-a is "Yes, don't worry", then please ignore this case.) Same as case 1-a but app gave timeout option to wakelock, say 3 seconds. Is this timeout option kept valid?

案例2-A:
请想象一下还有哪些是(通过广播接收器)开始通过AlarmManager服务和服务已经获得了wakelock(W / O超时选项)。该服务旨在使wakelock收购的时间最短。但不幸的是,Android操作系统挑这个服务杀因内存紧缩。 (我不知道,如果操作系统不会杀了服务时,获得wakelock,但我猜操作系统并不关心,但我希望操作系统会释放wakelock后)发生了wakelock什么?

Case 2-a:
Please imagine there is a service which was started by AlarmManager (via Broadcast receiver) and the service has acquired a wakelock (w/o timeout option). This service is designed to make wakelock-acquired-time minimum. But unfortunately, Android OS picked this service to kill due to memory crunch. (I don't know if OS won't kill service when wakelock is acquired, but I guess OS doesn't care. But I hope OS will release wakelock later.) What happens to that wakelock?

案例2-B:
(如果回答情况下,2-a是是的,别担心,那么请忽略这种情况。) 同的情况下2-A,但服务给超时选项wakelock,说3秒。难道这超时选项保持有效?

Case 2-b:
(If answer to case 2-a is "Yes, don't worry", then please ignore this case.) Same as case 2-a but service gave timeout option to wakelock, say 3 seconds. Is this timeout option kept valid?

WakeLock实施概述

当我们使用 pm.newWakeLock 来创建一个新的wakelock,在电源管理器简单地创建一个新的WakeLock对象,回报。所述WakeLock对象不是粘合剂对象,因此它不能被通过多个进程使用。然而,在该WakeLock对象,它包含名为mToken一个活页夹对象。

When we use pm.newWakeLock to create a new wakelock, the PowerManager simply creates a new WakeLock object and returns. The WakeLock object is not a binder object, so it cannot be used through multiple processes. However, in that WakeLock object, it contains a Binder object named 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会帮你回答你的问题时,工作。

Look at how PowerManagerService works when acquiring or releasing a wakelock will help you answer your question.

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)。这锁定正是我们之前所提到的mToken。此方法注册接收方(即 wakeLock )的通知,如果这粘结剂消失。如果该粘合剂对象意外消失(通常是因为它的宿主进程已被杀死),那么 binderDied 方法被调用的收件人。

The key statement is the lock.linkToDeath(wakeLock, 0);. That lock is exactly the mToken we mentioned before. This method registers the recipient (the wakeLock) for a notification if this binder goes away. If this binder object unexpectedly goes away (typically because its hosting process has been killed), then the binderDied method will get called on the recipient.

请注意,WakeLock在 PowerManagerService 从WakeLock不同的电源管理器,它是 IBinder.DeathRecipient 。因此,检查其 binderDied 方法。

Notice that the WakeLock in PowerManagerService is different from the WakeLock in PowerManager, it is an implementation of IBinder.DeathRecipient. So check out its binderDied method.

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

handleWakeLockDeath 将释放wakelock。

The handleWakeLockDeath will release that 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();
    }
}

所以我觉得在这两种情况下,在你的问题,答案是不用担心。至少在的Andr​​oid 4.2(其中code来自),这是事实。此外,在电源管理器在WakeLock类的finalize方法,但是这不是关键,你的问题。

So I think in both cases in your question, the answer is don't worry. At least in Android 4.2 (where the code comes from), it is true. Moreover, there is a finalize method on the WakeLock class in PowerManager, but this is not the key to your question.