Android 使用部分唤醒锁定保持后台线程的活动状态
我需要定期在后台运行任务,并使CPU保持清醒。根据安卓的说法,我使用了部分唤醒锁来实现这一目的。 为了测试唤醒锁,我编写了一个服务,它使用ScheduledThreadPoolExecutor每隔2分钟启动一个线程。此线程只需在SD卡中的日志文件上写入一个字符串 然后,我执行了以下简单的测试:运行应用程序并将设备从电源上拔下。正确执行2或3小时后,服务将停止运行线程,并且不会在日志文件中写入新字符串 服务代码:Android 使用部分唤醒锁定保持后台线程的活动状态,android,multithreading,background,powermanager,Android,Multithreading,Background,Powermanager,我需要定期在后台运行任务,并使CPU保持清醒。根据安卓的说法,我使用了部分唤醒锁来实现这一目的。 为了测试唤醒锁,我编写了一个服务,它使用ScheduledThreadPoolExecutor每隔2分钟启动一个线程。此线程只需在SD卡中的日志文件上写入一个字符串 然后,我执行了以下简单的测试:运行应用程序并将设备从电源上拔下。正确执行2或3小时后,服务将停止运行线程,并且不会在日志文件中写入新字符串 服务代码: @Override public int onStartCommand(Intent
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Service onStartCommand");
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiOpp wakeLock");
wakeLock.acquire();
TestTask testTask = new TestTask(getApplicationContext());
ScheduledThreadPoolExecutor monitorPool = new ScheduledThreadPoolExecutor(1);
monitorPool.scheduleAtFixedRate(testTask, 0, 120, TimeUnit.SECONDS);
return START_STICKY;
}
TestTask的代码:
@Override
public void run() {
//write on log file
LogManager.getInstance().logData("I am running!");
}
我希望在关闭显示时也会执行线程,但查看我的日志文件,情况似乎并非如此。我错在哪里?在安卓6.0+上,基本上会取消唤醒锁。一些制造商生产的6.0之前的设备也做了类似的事情
可以避免打瞌睡模式吗
用户可以将您的应用添加到电池优化白名单中。请注意,如果这是您的分销渠道之一,请通过操作\u请求\u忽略\u电池\u优化
要求用户执行此操作
或者,用户可以一直将设备放在充电器上
如果轮询周期不太频繁,可以尝试使用AlarmManager
使用setAndAllowHileIDLE()
或setExactAndAllowHileIDLE()
。充其量,你将每9分钟获得一次控制权。不过,您可能无法访问Internet
否则,每N分钟进行一次设备端轮询的方法将失败
谷歌希望您使用GCM/FCM,并在需要时让您的服务器按下信息,从而避免轮询。我不知道这是否与您的用例相关。在Android 6.0+上,基本上会撤消唤醒锁。一些制造商生产的6.0之前的设备也做了类似的事情
可以避免打瞌睡模式吗
用户可以将您的应用添加到电池优化白名单中。请注意,如果这是您的分销渠道之一,请通过操作\u请求\u忽略\u电池\u优化
要求用户执行此操作
或者,用户可以一直将设备放在充电器上
如果轮询周期不太频繁,可以尝试使用AlarmManager
使用setAndAllowHileIDLE()
或setExactAndAllowHileIDLE()
。充其量,你将每9分钟获得一次控制权。不过,您可能无法访问Internet
否则,每N分钟进行一次设备端轮询的方法将失败
谷歌希望您使用GCM/FCM,并在需要时让您的服务器按下信息,从而避免轮询。我不知道这是否与您的用例相关。您测试的是哪个版本的Android,以及具体的硬件?安卓6.0引入了打盹模式,各个制造商都有自己的积极节能模式,这些模式早于打盹。在现代安卓设备上,每两分钟做一次(使用
ScheduledExecutorService
、AlarmManager
、JobScheduler
等)是不可能的,除非用户将你的应用程序添加到电池优化白名单中。我使用的是Nexus 5(安卓6.0.1)和Nexus 6(安卓7)。是否可以避免打瞌睡模式?@commonware这是否也适用于创建类似“new MyThread().start()”的工作线程?我读过《android开发者指南》,但它只谈到AlarmManager和网络相关的工作。。它只提到了一次“延迟后台CPU”,对此没有任何解释。@Jenix:“这也适用于像“new MyThread().start()”这样的东西吗?”--是的。@Commonware谢谢!!你救了我。。我从来没有想过:(你在测试什么版本的Android,在什么特定的硬件上?Android 6.0引入了打瞌睡模式,不同的制造商都有自己的积极节能模式,这些模式早于打瞌睡。每两分钟做一次(使用ScheduledExecutorService
、AlarmManager
、JobScheduler
等)在现代Android设备上是不可能的,除非用户将您的应用程序添加到电池优化白名单中。我使用的是Nexus 5(Android 6.0.1)和Nexus 6(Android 7)。是否可以避免打瞌睡模式?@commonware这是否也适用于创建了“new MyThread().start()”之类的工作线程?我阅读了《android开发者指南》,但它只讨论了AlarmManager和网络相关作业。它只提到了一次“延迟后台CPU”,根本没有解释。@Jenix:“这也适用于像‘new MyThread().start()’这样的东西吗?”--是的。@commonware谢谢!!你救了我一命..我从没想过它会:(非常感谢@commonware。是的,这些信息对我的案例非常有用。我的目标是能够定期在后台执行P2P对等发现,以便在附近找到新设备。使用AlarmManager(每9分钟一次)我可以使用WifiP2P框架吗?@MattiaCampana:我还没有玩过WifiP2P。但是,除非你还持有一个WifiLock
,否则我希望在打瞌睡时WifiLock不可用,我不知道在打瞌睡时是否有一个WifiLock
就足够了。WifiLock
和打瞌睡之间的交互是不成文的ed AFAIK@Commonware噢,还有一件事!仍然不确定WifiLock?这个()没有特别提到Doze,但它建议使用WifiLock进行流媒体传输,所以我想WifiLock已经足够了。你认为呢?@Jenix:“仍然不确定WifiLock?”——正确。我没有玩过这个场景。你认为呢?“--我想说,WifiLock
可能是必要的。它是否足够是另一回事,我不知道,对不起。非常感谢@commonware。是的,这个信息对我的情况非常有用。我的