From bd1bc4067ff87ce1a21d12a48b1695fe58c8dd4d Mon Sep 17 00:00:00 2001 From: Dan Zivkovic <zivkovic@google.com> Date: Mon, 9 Mar 2015 14:48:51 -0700 Subject: [PATCH] ExecutorUtils lets use schedule a runnable chain. Bug 19625976. Change-Id: Iebbef7fed57a381498301dcf26fefa27d06802f7 --- .../latin/ContactsContentObserver.java | 4 +- .../latin/utils/ExecutorUtils.java | 60 +++++++++++-------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java index 04c1cf3339..4a8d1133b2 100644 --- a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java +++ b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java @@ -56,8 +56,8 @@ public class ContactsContentObserver implements Runnable { mContentObserver = new ContentObserver(null /* handler */) { @Override public void onChange(boolean self) { - ExecutorUtils.getBackgroundExecutor() - .execute(ContactsContentObserver.this); + // TODO(zivkovic): Schedule a separate task to reset the decoder. + ExecutorUtils.getBackgroundExecutor().execute(ContactsContentObserver.this); } }; final ContentResolver contentResolver = mContext.getContentResolver(); diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java index b21538caa0..b04a820aad 100644 --- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java @@ -23,7 +23,9 @@ import com.android.inputmethod.annotations.UsedForTesting; import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; /** * Utilities to manage executors. @@ -35,6 +37,20 @@ public class ExecutorUtils { private static final ScheduledExecutorService sExecutorService = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory()); + private static class ExecutorFactory implements ThreadFactory { + @Override + public Thread newThread(final Runnable runnable) { + Thread thread = new Thread(runnable, TAG); + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable ex) { + Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex); + } + }); + return thread; + } + } + @UsedForTesting private static ScheduledExecutorService sExecutorServiceForTests; @@ -44,6 +60,10 @@ public class ExecutorUtils { sExecutorServiceForTests = executorServiceForTests; } + // + // Public methods used to schedule a runnable for execution. + // + /** * @return scheduled executor service used to run background tasks */ @@ -54,38 +74,28 @@ public class ExecutorUtils { return sExecutorService; } - /** - * Shutdowns all executors and removes all executors from the executor map for testing. - */ - @UsedForTesting - public static void shutdownAllExecutors() { - sExecutorService.execute(new ExecutorShutdown(sExecutorService)); - } - - private static class ExecutorFactory implements ThreadFactory { - @Override - public Thread newThread(final Runnable runnable) { - Thread thread = new Thread(runnable, TAG); - thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable ex) { - Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex); - } - }); - return thread; - } + public static Runnable chain(final Runnable... runnables) { + return new RunnableChain(runnables); } - private static class ExecutorShutdown implements Runnable { - private final ScheduledExecutorService mExecutor; + private static class RunnableChain implements Runnable { + private final Runnable[] mRunnables; - public ExecutorShutdown(final ScheduledExecutorService executor) { - mExecutor = executor; + private RunnableChain(final Runnable... runnables) { + if (runnables == null || runnables.length == 0) { + throw new IllegalArgumentException("Attempting to construct an empty chain"); + } + mRunnables = runnables; } @Override public void run() { - mExecutor.shutdown(); + for (Runnable runnable : mRunnables) { + if (Thread.interrupted()) { + return; + } + runnable.run(); + } } } } -- GitLab