title: How does Worker.setForegroundAsync work behind the scene?
body: <p>Currently, after quit the app, to complete a long running task in foreground (So that it will not be killed by OS), this is what I did by using <code>WorkManager</code>.</p>
  
  <ol>
  <li>Use <code>Worker</code> to call <code>ContextCompat.startForegroundService</code>, for starting an <code>IntentService</code>.</li>
  <li><code>Worker</code> will then return <code>Result.success()</code> immediately.</li>
  <li>In <code>onHandleIntent</code> on <code>IntentService</code>, it will execute <code>startForeground</code>, before performing long running task.</li>
  </ol>
  
  <p>Here's the code snippet.</p>
  
  <pre><code>public class SyncWorker extends Worker {
      @NonNull
      @Override
      public Result doWork() {
          final Intent intent = new Intent(WeNoteApplication.instance(), SyncForegroundIntentService.class);
  
          ContextCompat.startForegroundService(
                  WeNoteApplication.instance(),
                  intent
          );
  
          return Result.success();
      }
  }
  
  public class SyncForegroundIntentService extends IntentService {
      private static final String TAG = "com.yocto.wenote.sync.SyncIntentService";
  
      public SyncForegroundIntentService() {
          super(TAG);
      }
  
      @Override
      protected void onHandleIntent(@Nullable Intent intent) {
  
          final Context context = WeNoteApplication.instance();
  
          NotificationCompat.Builder builder = new NotificationCompat.Builder(...
  
          startForeground(SYNC_FOREGROUND_INTENT_SERVICE_ID, builder.build());
  
          // Perform networking operation within foreground service.
  
          stopForeground(true);
  </code></pre>
  
  <hr>
  
  <p>I have strong intention to migrate the code, to make use of <a href="https://developer.android.com/reference/androidx/work/ListenableWorker#setForegroundAsync(androidx.work.ForegroundInfo)" rel="nofollow noreferrer"><code>setForegroundAsync</code></a> in <code>WorkManager</code>. The reason is that, under certain rare circumstance, I will get the following crash</p>
  
  <blockquote>
    <p>Context.startForegroundService() did not then call
    Service.startForeground()</p>
  </blockquote>
  
  <p>So, I thought migrating to <code>setForegroundAsync</code> might help eliminating this problem.</p>
  
  <hr>
  
  <p>However, it isn't clear how <code>setForegroundAsync</code> work behind the scene, by looking at <a href="https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager/src/main/java/androidx/work/impl/utils/WorkForegroundUpdater.java?autodive=0%2F%2F%2F" rel="nofollow noreferrer">WorkForegroundUpdater souce code</a>.</p>
  
  <p>Here's the code snippet of <code>setForegroundAsync</code> code example from <a href="https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running" rel="nofollow noreferrer">https://developer.android.com/topic/libraries/architecture/workmanager/advanced/long-running</a></p>
  
  <pre><code>public class DownloadWorker extends Worker {
      public DownloadWorker(
          @NonNull Context context,
          @NonNull WorkerParameters parameters) {
              ...
      }
  
      @NonNull
      @Override
      public Result doWork() {
          ...
  
          // What happens behind the scene?!
          setForegroundAsync(createForegroundInfo(progress));
  
          // The long running task is still executed in Worker thread.
          download(inputUrl, outputFile);
  
          return Result.success();
      }
  </code></pre>
  
  <hr>
  
  <p>However, it isn't clear whether such migration will achieve equivalent outcome. As, here are their differences.</p>
  
  <h2>Before migration to setForegroundAsync</h2>
  
  <ol>
  <li>The long running task is executed by <code>IntentService</code>'s user thread.</li>
  <li>Before long running task is completed, Worker will return immediately.</li>
  </ol>
  
  <h2>After migration to setForegroundAsync</h2>
  
  <ol>
  <li>The long running task is executed by <code>Worker</code>'s user thread.</li>
  <li>Worker will only return after long running task is finished executing.</li>
  </ol>
  
  <hr>
  
  <p>Currently, with my current implementation, I will able to avoid <a href="https://stackoverflow.com/questions/54985675/still-getting-excessive-network-usage-background-warning-after-running-netwo">Excessive network usage (background)</a> issue. I am not sure whether with <code>setForegroundAsync</code>, will I still able to avoid <a href="https://stackoverflow.com/questions/54985675/still-getting-excessive-network-usage-background-warning-after-running-netwo">Excessive network usage (background)</a> issue?</p>
  
  <p>In short, does anyone has idea how Worker.setForegroundAsync work behind the scene?</p>