gpt4 book ai didi

android - 在 BroadcastReceiver 中获取 WakeLock 并在 Service 中释放它的正确模式

转载 作者:IT王子 更新时间:2023-10-28 23:32:12 24 4
gpt4 key购买 nike

即使经过大量研究,我仍然不能完全确定我是如何为由 BroadcastReceiver 启动的 Service 实现 WakeLock 的方式> 是正确的——尽管它似乎工作正常。广播接收器从警报中获取 Intent 发送给它,因此首先从 AlarmManager 的 API 文档开始:

If your alarm receiver called Context.startService(), it is possible that the phone will sleep before the requested service is launched. To prevent this, your BroadcastReceiver and Service will need to implement a separate wake lock policy to ensure that the phone continues running until the service becomes available.

所以,在 onReceive() 我这样做:

    Intent serviceIntent = new Intent(context, SomeService.class);
context.startService(serviceIntent);

if(SomeService.wakeLock == null) {
PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
SomeService.wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
SomeService.WAKE_LOCK_TAG);
}
if(! SomeService.wakeLock.isHeld()) {
SomeService.wakeLock.acquire();
}

在我所做的服务中:

    try {
// Do some work
} finally {
if(wakeLock != null) {
if(wakeLock.isHeld()) {
wakeLock.release();
}
wakeLock = null;
}
}

SomeService.wakeLock字段是包私有(private)、静态和易变的。

我不确定的是使用 isHeld() 进行的检查 - 它是否真的告诉我是否获得了 WakeLock,我是否需要这样做检查吗?

最佳答案

What I am unsure about is the check using isHeld() - does it really tell me if a WakeLock is acquired or not, and do I need to do this check at all?

实际上回答起来有点棘手。查看 PowerManager 的来源和 PowerManager.WakeLock here WakeLock.acquire()WakeLock.acquireLocked()方法如下...

public void acquire(long timeout) {
synchronized (mToken) {
acquireLocked();
mHandler.postDelayed(mReleaser, timeout);
}
}

private void acquireLocked() {
if (!mRefCounted || mCount++ == 0) {
// Do this even if the wake lock is already thought to be held (mHeld == true)
// because non-reference counted wake locks are not always properly released.
// For example, the keyguard's wake lock might be forcibly released by the
// power manager without the keyguard knowing. A subsequent call to acquire
// should immediately acquire the wake lock once again despite never having
// been explicitly released by the keyguard.
mHandler.removeCallbacks(mReleaser);
try {
mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
} catch (RemoteException e) {
}
mHeld = true;
}
}

... mServiceIPowerManager接口(interface)及其来源不可用,因此在尝试调用 acquireWakeLock(...) 时很难判断可能会或可能不会出错的地方.

无论如何,唯一可以捕获的异常是RemoteExceptioncatch block 什么都不做。紧接在 try/catch 之后,mHeld设置true无论如何。

简而言之,如果您调用 isHeld()紧接在 acquire() 之后结果将始终为 true .

进一步查找 PowerManager.WakeLock 的来源release() 的行为相似调用 release(int flags) mHeld成员始终设置为 false不管发生什么。

最后,我建议检查 isHeld() 总是一个好主意。作为一种最佳实践,以防更高版本的 Android 更改 WakeLock 的这种行为。方法。

关于android - 在 BroadcastReceiver 中获取 WakeLock 并在 Service 中释放它的正确模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7182002/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com