Merge "Deprecate implicit Handler constructors"
am: 560c3ebe1e

Change-Id: I254f85c07743883c7d350a47750dad0745c47d52
diff --git a/api/current.txt b/api/current.txt
index 94ad6fa..4ba4fbe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34548,8 +34548,8 @@
   }
 
   public class Handler {
-    ctor public Handler();
-    ctor public Handler(@Nullable android.os.Handler.Callback);
+    ctor @Deprecated public Handler();
+    ctor @Deprecated public Handler(@Nullable android.os.Handler.Callback);
     ctor public Handler(@NonNull android.os.Looper);
     ctor public Handler(@NonNull android.os.Looper, @Nullable android.os.Handler.Callback);
     method @NonNull public static android.os.Handler createAsync(@NonNull android.os.Looper);
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 9af9eda..a99bdabe 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -28,15 +28,14 @@
  * A Handler allows you to send and process {@link Message} and Runnable
  * objects associated with a thread's {@link MessageQueue}.  Each Handler
  * instance is associated with a single thread and that thread's message
- * queue.  When you create a new Handler, it is bound to the thread /
- * message queue of the thread that is creating it -- from that point on,
- * it will deliver messages and runnables to that message queue and execute
- * them as they come out of the message queue.
- * 
+ * queue. When you create a new Handler it is bound to a {@link Looper}.
+ * It will deliver messages and runnables to that Looper's message
+ * queue and execute them on that Looper's thread.
+ *
  * <p>There are two main uses for a Handler: (1) to schedule messages and
  * runnables to be executed at some point in the future; and (2) to enqueue
  * an action to be performed on a different thread than your own.
- * 
+ *
  * <p>Scheduling messages is accomplished with the
  * {@link #post}, {@link #postAtTime(Runnable, long)},
  * {@link #postDelayed}, {@link #sendEmptyMessage},
@@ -114,7 +113,18 @@
      *
      * If this thread does not have a looper, this handler won't be able to receive messages
      * so an exception is thrown.
+     *
+     * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
+     *   where operations are silently lost (if the Handler is not expecting new tasks and quits),
+     *   crashes (if a handler is sometimes created on a thread without a Looper active), or race
+     *   conditions, where the thread a handler is associated with is not what the author
+     *   anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
+     *   explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
+     *   similar. If the implicit thread local behavior is required for compatibility, use
+     *   {@code new Handler(Looper.myLooper())} to make it clear to readers.
+     *
      */
+    @Deprecated
     public Handler() {
         this(null, false);
     }
@@ -128,7 +138,17 @@
      * so an exception is thrown.
      *
      * @param callback The callback interface in which to handle messages, or null.
+     *
+     * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs
+     *   where operations are silently lost (if the Handler is not expecting new tasks and quits),
+     *   crashes (if a handler is sometimes created on a thread without a Looper active), or race
+     *   conditions, where the thread a handler is associated with is not what the author
+     *   anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper
+     *   explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or
+     *   similar. If the implicit thread local behavior is required for compatibility, use
+     *   {@code new Handler(Looper.myLooper(), callback)} to make it clear to readers.
      */
+    @Deprecated
     public Handler(@Nullable Callback callback) {
         this(callback, false);
     }