0

在来自CWAC Wakeful 库WakefileIntentService.java中,代码包含:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    PowerManager.WakeLock lock = getLock(this.getApplicationContext());
    if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0) {
        lock.acquire();
    }
    super.onStartCommand(intent, flags, startId);
    return(START_REDELIVER_INTENT);
}

为什么要检查代码START_FLAG_REDELIVERY- 是什么阻止了以下情况?

  1. onStartCommand()被调用并获得锁。
  2. 系统在完成之前终止服务。
  3. 系统使用 重新传递意图,导致对已持有的锁的START_FLAG_REDELIVERY另一个调用。acquire()
  4. 服务完成并调用release()一次。
  5. 由于被获取了两次但只释放了一次,因此引用计数锁仍然永远持有。
4

3 回答 3

1

如果服务被杀死,那么它的执行过程就会终止,稍后当它重新启动时,锁就不再持有了。您可以在此代码段中看到锁只是保存在一个静态变量中。

synchronized private static PowerManager.WakeLock getLock(Context context) {
    if (lockStatic == null) {
      PowerManager mgr=
          (PowerManager)context.getSystemService(Context.POWER_SERVICE);

      lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NAME);
      lockStatic.setReferenceCounted(true);
    }

    return(lockStatic);
  }

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/w8BdsI1BVdA

于 2013-02-04T04:52:53.453 回答
0

似乎是为了在进程被杀死后重新获取锁,但是当另一个意图服务已经使用锁运行时,在这种情况下,它需要增加重新传递的意图的引用计数,因为来自 sendWakefulWork() 的原始锁定在旧的过程中不再存在。

由于未处理 START_FLAG_RETRY 似乎很奇怪,我为此打开了问题https://github.com/commonsguy/cwac-wakeful/issues/10

于 2013-02-05T09:46:17.703 回答
0

是什么阻止了以下情况?

您的场景意味着 Android 将终止服务并留下WakeLock未完成的服务。我知道不会发生这种情况。Android 会终止进程,而不是服务,并且操作系统有责任释放此时获取WakeLock的任何内容。

由于未处理 START_FLAG_RETRY 似乎很奇怪,我为此打开了问题https://github.com/commonsguy/cwac-wakeful/issues/10

正如我在那个问题中指出的那样,虽然START_FLAG_REDELIVERY有不错的文档,START_FLAG_RETRY但没有。我不知道它什么时候会被使用。我不知道WakeLock基于那些无证原因的遗嘱状态是什么。等等。冒着偶然意外睡眠的风险,总比意外地让 CPU 无限期开机要好得多。

于 2013-02-07T00:36:16.427 回答