【问题标题】:Releasing timed WakeLock manually手动释放定时唤醒锁
【发布时间】:2014-02-28 16:16:58
【问题描述】:

在我的后台服务中,我使用acquire()(不带参数)获取部分唤醒锁,并在我不再需要它时手动释放它。

当时,一些 Xperia 用户抱怨 Xperia 的耐力模式存在问题。我找到了这篇文章:Optimizing for Sony's Stamina Mode

  1. 不要使用唤醒锁 唤醒锁通常对功耗非常不利,因为它们使整个 Android 系统保持唤醒状态。如果使用了唤醒锁,请确保它们是定时唤醒锁,这样被占用的唤醒锁不会存在太长时间。计时您的唤醒锁,以便在您的任务完成后释放它。您可以在 Java Monday 的示例中看到它的使用情况。

所以我开始使用定时唤醒锁(使用acquire(timeout) 而不是acquire())。问题在于发布。我仍在手动释放,因为在大多数情况下,在超时到期之前我将不再需要锁。

问题在于自动释放。我会解释的。定时获取是这样实现的(取自 android-19 来源):

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

mReleaser 初始化如下(来自 android-19 来源):

private final Runnable mReleaser = new Runnable() {
    public void run() {
        release();
    }
};

如果不再持有锁,release() 会抛出 RuntimeException:

public void release(int flags) {
    synchronized (mToken) {
        if (!mRefCounted || --mCount == 0) {
            mHandler.removeCallbacks(mReleaser);
            if (mHeld) {
                try {
                    mService.releaseWakeLock(mToken, flags);
                } catch (RemoteException e) {
                }
                mHeld = false;
            }
        }
        if (mCount < 0) {
            throw new RuntimeException("WakeLock under-locked " + mTag);
        }
    }
}

所以问题是当我手动释放它时,它仍然会在超时到期后尝试自动释放它,并且唤醒锁处于未锁定状态。

问题是:我怎样才能仍然使用定时唤醒锁,同时能够在超时到期之前手动释放它?

【问题讨论】:

    标签: android wakelock


    【解决方案1】:

    作为一种解决方案(或解决方法 - 如果有人知道更好的解决方案,请发表评论)唤醒没有引用计数器的锁:

    mWakeLock.setReferenceCounted(false);
    

    这可以防止锁定不足

    【讨论】:

      【解决方案2】:

      在您在突出显示行上方复制的代码中,当引用计数降至零时,将删除由获取添加的回调,因此假设您正在获取然后每次获取仅释放一次,那么您应该没问题。如果你真的超时了,你怎么知道停止手动释放......

      if (!mRefCounted || --mCount == 0) {
         mHandler.removeCallbacks(mReleaser);           /// This removes the callback
         if (mHeld) {
              try {
                  mService.releaseWakeLock(mToken, flags);
              } catch (RemoteException e) {
              }
              mHeld = false;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多