title: Android - Handler repeating task stops executing while the screen is on at Foreground Service
body: <p>First of all, this is a long question but targeting only one topic, and I'm sorry I cannot share any code as it is a project of our company and is classified. We are using a foreground service that executes a task within 100 milliseconds only. Until I asked this question we used multiple approaches on executing a code in a short amount of time, follows:</p>
  
  <ul>
  <li>A thread with "Thread.sleep" in it (not the best approach but it was our first try, went inconsistent),</li>
  <li>A thread with "Object.wait" (same result as above),</li>
  <li><a href="https://developer.android.com/reference/java/util/Timer" rel="nofollow noreferrer">Timer</a> (also is inconsistent and stops executing after some time),</li>
  <li><a href="https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor" rel="nofollow noreferrer">ScheduledThreadPoolExecutor</a> which also has the problem of all above.</li>
  </ul>
  
  <p>On my phone (HUAWEI P20 Lite), after trying these approaches, we finally decided to use a <a href="https://developer.android.com/reference/android/os/Handler" rel="nofollow noreferrer">Handler</a> with a <a href="https://developer.android.com/reference/android/os/HandlerThread" rel="nofollow noreferrer">HandlerThread</a> as the work does not require to interact with UI thread. (not always but we are using a seperate handler for it.) In between every approach, this seems to be the most consistent one, however we don't know if it depends on the phone, manufacturer or anything, my phone stops executing the looping handler with postDelayed <strong>until I interact with the app UI in some way, for example: touching the notification, while the screen is on.</strong> Yes, I'm not talking about clicking the notification itself, but even touching, or like expanding the detail text starts the handler again. Which means, I think my phone is trying to save power with pausing the background execution. </p>
  
  <p>Now, we only want to run this method while the screen is on, as we are already pausing the handler itself via "a screen on-off broadcast receiver" that registered in the foreground service by removing the callbacks of the runnable, but after screen goes on, broadcast is received but even if "Handler.post()" executes, it does not run the runnable inside, hence it never loops.</p>
  
  <p>To give you a bit of context, this is what kind of logic we are following:</p>
  
  <p>We open a foreground service with something similar to the below code:</p>
  
  <pre><code>if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O)
  {
      getApplicationContext().startForegroundService(
          new Intent(getApplicationContext(),
                     MyService.class));
  }
  else
  {
      getApplicationContext().startService(
           new Intent(getApplicationContext(), MyService.class));
  }
  </code></pre>
  
  <p>And then, inside the service we do something like the following:</p>
  
  <pre><code>public int onStartCommand()
  {
      // notification stuff
  
      HandlerThread thread = new HandlerThread("myThread");
      thread.start();
  
      Handler handler = new Handler(thread.getLooper());
      handler.post(new Runnable() 
      {
           // do stuff
           // this runnable stops executing after some time. This is where the problem lies.
           handler.postDelayed(this, 100);
      })
  
      return START_STICKY;
  }
  </code></pre>
  
  <p>The handler inside onStartCommand is unstable, sometimes it does not respect the delay, or sometimes it does not execute at all. Now, not respecting the delay is not the problem as we don't have to be that consistent as our calculations do not depend on the elapsed time or something, but if it stops executing (which in this case, it does), that's where the problem starts. </p>
  
  <p>To handle this, we are going to use a brand new class that Android Jetpack offers, <a href="https://developer.android.com/topic/libraries/architecture/workmanager/" rel="nofollow noreferrer">WorkManager</a>, which is perfect for checking the status of handlers. To understand if the threads are active or not, we registered the last execution time of the code inside the handler and are going to access it via the worker class. Now, if the handlers are down, we would like to wake these handlers up. How can this be done? Because remember, <strong>this happens while the screen is on.</strong></p>
  
  <p>Edit: Here are some logs about how the thread execution goes.</p>
  
  <pre><code>//2018-12-19 11:35:15.048 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  //2018-12-19 11:35:15.154 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  2018-12-19 11:35:15.262 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  2018-12-19 11:35:45.262 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  //2018-12-19 11:35:45.365 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  //2018-12-19 11:35:45.468 17222-17952/com.example.something D/MyService: threadName: MainThread, postDelayedValue: true
  </code></pre>
  
  <p>Any suggestions? Any workarounds for this? Every help and comment is appreciated, thank you so much.</p>