I have created a dummy IntentService
that runs in the foreground which essentially just logs how long it has been awake every 5 seconds. This has run for several hours on a test device without requiring any WakeLock
permissions. Furthermore, it doesn't seem to hurt the battery life at all. Doesn't show up as using even 1% of battery in the battery stats on the device. How can this service continually run without requiring a WakeLock
?
Update: Some interesting behavior I noticed from this. It seems that the service is actually going to sleep, but on a fairly inconsistent basis. Looking back through some of the log statements you can see that even though the thread is sleeping for 5 seconds only, then waking up, the system appears to be pausing the service. Notice the time jumps from 17:56:31 to 17:56:54 to 17:57:05. A 23 second jump followed by a 9 second jump. Explanation on why this is would be most helpful. Thank you.
12-01 17:56:31.479 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2375000 Seconds
12-01 17:56:54.630 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2380000 Seconds
12-01 17:57:05.632 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2385000 Seconds
12-01 17:57:11.097 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2390000 Seconds
12-01 17:57:16.098 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2395000 Seconds
12-01 17:58:00.829 8723-8780/com.example.timedrift D/Done Sleeping﹕ Active for 2400000 Seconds
IntentService:
@Override
protected void onHandleIntent(Intent intent) {
Notification notification = new Notification(R.drawable.ic_launcher, "Time",
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, "Time",
"Time", pendingIntent);
startForeground(100, notification);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPrefs.edit();
try {
Log.d("TimerService", "Start");
int i = 1;
while(true){
Thread.sleep(5000);
int numberOfSeconds = i++*5;
Log.d("Done Sleeping", String.valueOf("Active for "+numberOfSeconds+" Seconds"));
editor.putLong(String.valueOf(numberOfSeconds), numberOfSeconds);
editor.apply();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
The timing data you provided actually does show that the device as a whole is going to sleep. Your call to
sleep()
is sleeping your current thread of yourService
for a minimum of 5 seconds. The scheduler is usually +/- 10ms on these types of operations. Without a wakelock, the system as a whole will sleep and this will have no effect on your service lifecycle. Something else on the device is waking the system (could be network events, alarms, other services, etc.) Which in turn is causing your app to get scheduled before the next sleep. The fact that your service is a foreground one minimizes the risk of it being killed due to low resources, but doesn't do anything to prevent low power handling by the system.