io.flutter.plugins.googlesignin.BackgroundTaskRunner.java Source code

Java tutorial

Introduction

Here is the source code for io.flutter.plugins.googlesignin.BackgroundTaskRunner.java

Source

// Copyright 2017, the Flutter project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package io.flutter.plugins.googlesignin;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * A class for running tasks in a background thread.
 *
 * <p>TODO(jackson): If this class is useful for other plugins, consider including it in a shared
 * library or in the Flutter engine
 */
public final class BackgroundTaskRunner {

    /**
     * Interface that callers of this API can implement to be notified when a {@link
     * #runInBackground(Callable,Callback) background task} has completed.
     */
    public interface Callback<T> {
        /**
         * Invoked on the UI thread when the specified future has completed (calling {@code get()} on
         * the future is guaranteed not to block). If the future completed with an exception, then
         * {@code get()} will throw an {@code ExecutionException}.
         */
        void run(Future<T> future);
    }

    private final ThreadPoolExecutor executor;

    /**
     * Creates a new background processor with the given number of threads.
     *
     * @param threads The fixed number of threads in ther pool.
     */
    public BackgroundTaskRunner(int threads) {
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        // Only keeps idle threads open for 1 second if we've got more threads than cores.
        executor = new ThreadPoolExecutor(threads, threads, 1, TimeUnit.SECONDS, workQueue);
    }

    /**
     * Executes the specified task in a background thread and notifies the specified callback once the
     * task has completed (either successfully or with an exception).
     *
     * <p>The callback will be notified on the UI thread.
     */
    public <T> void runInBackground(Callable<T> task, final Callback<T> callback) {
        final ListenableFuture<T> future = runInBackground(task);
        future.addListener(new Runnable() {
            @Override
            public void run() {
                callback.run(future);
            }
        }, Executors.uiThreadExecutor());
    }

    /**
     * Executes the specified task in a background thread and returns a future with which the caller
     * can be notified of task completion.
     *
     * <p>Note: the future will be notified on the background thread. To be notified on the UI thread,
     * use {@link #runInBackground(Callable,Callback)}.
     */
    public <T> ListenableFuture<T> runInBackground(final Callable<T> task) {
        final SettableFuture<T> future = SettableFuture.create();

        executor.execute(new Runnable() {
            @Override
            public void run() {
                if (!future.isCancelled()) {
                    try {
                        future.set(task.call());
                    } catch (Throwable t) {
                        future.setException(t);
                    }
                }
            }
        });

        return future;
    }
}