使用PARTIAL_WAKE_LOCK保持活动背景线程

时间:2016-12-14 22:50:28

标签: android multithreading background powermanager

我需要定期在后台运行任务,并保持唤醒CPU。根据Android documentation我为此目的使用了 PARTIAL_WAKE_LOCK 。 为了测试唤醒锁,我编写了一个服务,它使用 ScheduledThreadPoolExecutor 每2分钟启动一个线程。这个线程只是在sdcard的日志文件中写一个字符串。

然后,我执行了以下简单测试:运行应用程序并从电源上拔下设备。正确执行2或3个小时后,服务停止运行该线程,并且日志文件中不会写入新的字符串。

服务代码:

@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!");
}

我希望在关闭显示器时也执行该线程,但查看我的日志文件似乎不是这样。我哪里错了?

1 个答案:

答案 0 :(得分:3)

在Android 6.0及更高版本中,Doze mode基本上会撤消你的唤醒锁。一些制造商的6.0之前的设备做了类似的事情。

  

是否可以避免打盹模式?

用户可以将您的应用添加到电池优化白名单中。请注意,要求用户通过ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS may result in your app being banned from the Play Store执行此操作,如果这是您的分销渠道之一。

或者,用户可以随时将设备保持在充电器上。

如果您可以在较短的轮询期内过关,可以使用setAndAllowWhileIdle()尝试setExactAndAllowWhileIdle()AlarmManager。充其量,您将每9分钟获得一次控制权。但是,您可能无法访问Internet。

否则,设备端民意调查 - 每N分钟的方法注定要失败。

Google希望您使用GCM / FCM并避免轮询,方法是在需要时让服务器下载信息。我不知道这是否与您的用例相关。