【问题标题】:Why do WakefulIntentService check START_FLAG_REDELIVERY?为什么 WakefulIntentService 会检查 START_FLAG_REDELIVERY?
【发布时间】:2013-02-04 03:18:08
【问题描述】:

在来自CWAC Wakeful libraryWakefileIntentService.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. 由于被获取两次但仅释放一次,引用计数锁仍然永久持有。

【问题讨论】:

    标签: android android-service android-lifecycle wakelock commonsware-cwac


    【解决方案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

    【讨论】:

    • 但是如果没有持有锁,就不需要检查START_FLAG_REDELIVERY。那么问题来了,为什么要检查flag,即使锁住了仍然再次锁住呢?
    【解决方案2】:

    是什么阻止了以下情况?

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

    这似乎很奇怪,因为没有处理 START_FLAG_RETRY,我已经为此打开了问题 https://github.com/commonsguy/cwac-wakeful/issues/10

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

    【讨论】:

      【解决方案3】:

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

      这似乎很奇怪,因为没有处理 START_FLAG_RETRY,我已经为此打开了问题https://github.com/commonsguy/cwac-wakeful/issues/10

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 2016-12-04
        • 1970-01-01
        • 2013-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多