【问题标题】:AlarmManager wakelock and goAsync in receiver接收器中的 AlarmManager 唤醒锁和 goAsync
【发布时间】:2013-11-09 03:29:05
【问题描述】:

简介

根据AlarmManager Documentation

只要警报接收器的 onReceive() 方法正在执行,警报管理器就会持有 CPU 唤醒锁。这保证了在您完成广播处理之前手机不会休眠。一旦 onReceive() 返回,警报管理器就会释放这个唤醒锁。这意味着在某些情况下,一旦您的 onReceive() 方法完成,手机就会进入睡眠状态。如果您的警报接收器调用了 Context.startService(),则手机可能会在请求的服务启动之前休眠。为防止这种情况,您的 BroadcastReceiver 和 Service 将需要实施单独的唤醒锁定策略,以确保手机继续运行直到服务可用。

Android 也提供了WakefulBroadcastReceiver 来解决这个问题:

实现 BroadcastReceiver 的通用模式的助手,它接收设备唤醒事件,然后将工作传递给服务,同时确保设备在转换期间不会重新进入睡眠状态。

该类负责为您创建和管理部分唤醒锁;您必须请求 WAKE_LOCK 权限才能使用它。

从 api 级别 11 开始,BroadcastReceiver 提供了goAsync 方法,可以让接收器保持运行时间超过 10 秒,并将耗时的代码移动到后台线程。

问题

如果在警报管理器的接收器(继承自 BroadcastReceiver,而不是 WakefulBroadcastReceiver)的接收器中,我调用 goAsync 并为耗时的代码启动新线程,警报管理器将保持唤醒锁,直到我对从 goAsync 返回的pendingResult 调用完成还是我还需要在新线程上运行的代码中获取唤醒锁?

【问题讨论】:

  • which inherits from BroadcastReceiver, not BroadcastReceiver 什么?
  • @njzk2:哎呀.. 已修复。

标签: android multithreading broadcastreceiver alarmmanager wakelock


【解决方案1】:

"从api级别11开始BroadcastReceiver提供goAsync方法 允许接收器运行超过 10 秒和 将耗时的代码移到后台线程。”

根据文档,这是不正确的。引用goAsync doc:

这不会改变相对响应的期望 广播(10s内完成)

【讨论】:

  • 我认为这取决于您如何解释它:onReceive 应该在 10 秒内完成,但广播本身不会被破坏。 “这可以由 onReceive 中的应用程序调用,以允许它在从该函数返回后保持广播活动”。因此,您可以在新线程上开始长时间运行代码,并在完成后调用 PendingResult.finish。
  • @Giorgi 文档对我来说不是完全清楚,但我认为您的评论具有误导性:这不会改变对广播相对响应的期望(在 10 秒内完成),但确实允许实现将与其相关的工作转移到另一个线程,以避免由于磁盘 IO 而导致主 UI 线程出现故障。 - 对我来说,这意味着goAsync() 有仍然是 10 秒的限制,但至少 UI 不会阻塞。
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多