Java tutorial
// 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; } }