简体   繁体   English

使用PARTIAL_WAKE_LOCK保持后台线程活跃

[英]Keep alive a background thread using PARTIAL_WAKE_LOCK

I need to periodically run a task in background, and to keep awake the CPU. 我需要在后台定期运行任务,并保持CPU唤醒。 According to the Android documentation i used the PARTIAL_WAKE_LOCK for this purpose. 根据Android 文档,我为此使用PARTIAL_WAKE_LOCK In order to test the wake lock, i wrote a Service which starts a thread every 2 minutes using a ScheduledThreadPoolExecutor . 为了测试唤醒锁,我编写了一个Service,使用ScheduledThreadPoolExecutor每2分钟启动一个线程。 This thread just write a string on a log file in the sdcard. 该线程仅在sdcard中的日志文件上写入字符串。

Then, i performed the following simple test: run the application and unplug the device from the power. 然后,我执行了以下简单测试:运行应用程序,并断开设备的电源。 After 2 or 3 hours of correct execution, the Service stops to run the thread and no new strings are written in the log file. 正确执行2或3个小时后,服务将停止运行线程,并且不会在日志文件中写入新的字符串。

Service's code: 服务代码:

@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's code: TestTask的代码:

@Override
public void run() {
    //write on log file
    LogManager.getInstance().logData("I am running!");
}

I expect that the thread is also executed when the display is turned off, but looking my log file it seems not to be so. 我希望在关闭显示时也可以执行该线程,但是查看我的日志文件似乎并非如此。 Where am I wrong? 我哪里错了?

On Android 6.0+, Doze mode basically will undo your wakelock. 在Android 6.0+上, 打ze模式基本上会撤消您的唤醒锁。 Pre-6.0 devices from some manufacturers do similar things. 一些制造商的6.0之前版本的设备也做类似的事情。

Is it possible to avoid the Doze mode? 是否可以避免打ze睡模式?

The user can add your app to the battery optimization whitelist. 用户可以将您的应用添加到电池优化白名单中。 Note that asking users to do this via ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS may result in your app being banned from the Play Store , if that was to be one of your distribution channels. 请注意,要求用户通过ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS进行此ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 可能会导致您的应用被Play商店禁止 ,如果那是您的发行渠道之一。

Or, the user can keep their device on a charger all the time. 或者,用户可以始终将其设备放在充电器上。

If you can get by with a less-frequent polling period, you can try setAndAllowWhileIdle() or setExactAndAllowWhileIdle() with AlarmManager . 如果你可以用一个频率较低的轮询周期获得通过,你可以尝试setAndAllowWhileIdle()setExactAndAllowWhileIdle()AlarmManager At best, you will get control every 9 minutes. 充其量,您将每9分钟获得一次控制。 You may not have Internet access, though. 但是,您可能无法访问Internet。

Otherwise, a device-side poll-every-N-minutes approach is doomed. 否则,注定要在设备端每隔N分钟轮询一次。

Google wants you to use GCM/FCM and avoid the polling, by having your server push down information if and when this is needed. Google希望您在需要时以及通过服务器下推信息来使用GCM / FCM并避免轮询。 I do not know if that is relevant for your use case. 我不知道这是否与您的用例有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM