From bba231d7a63b58a8c2b174722ed1487b0f7d8270 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 14 Nov 2014 15:49:45 -0800 Subject: [PATCH] Explicitly bind AsyncTask to main looper. It seems we were sort of trying to do this by forcing the AsyncTask static initializer to run at certain times but it was not sufficiently reliable. In particular, this resulted in occasional system server crashes. Bug: 18192406 Change-Id: Ief73210c60e7680fbed6df74e3e58809b7ec7e4d --- core/java/android/app/ActivityThread.java | 2 -- .../java/android/content/ContentProvider.java | 6 ----- core/java/android/os/AsyncTask.java | 24 ++++++++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index a268b1c30fae9..e3de44e45d89f 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5223,8 +5223,6 @@ public final class ActivityThread { sMainThreadHandler = thread.getHandler(); } - AsyncTask.init(); - if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index c8f9b7dd80e2b..4c82efda7298c 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -1659,12 +1659,6 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } private void attachInfo(Context context, ProviderInfo info, boolean testing) { - /* - * We may be using AsyncTask from binder threads. Make it init here - * so its static handler is on the main thread. - */ - AsyncTask.init(); - mNoPerms = testing; /* diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 4f91d1993305a..7785f2bb886c6 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -209,9 +209,9 @@ public abstract class AsyncTask { private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; - private static final InternalHandler sHandler = new InternalHandler(); - private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; + private static InternalHandler sHandler; + private final WorkerRunnable mWorker; private final FutureTask mFuture; @@ -265,9 +265,13 @@ public abstract class AsyncTask { FINISHED, } - /** @hide Used to force static handler to be created. */ - public static void init() { - sHandler.getLooper(); + private static Handler getHandler() { + synchronized (AsyncTask.class) { + if (sHandler == null) { + sHandler = new InternalHandler(); + } + return sHandler; + } } /** @hide */ @@ -315,7 +319,7 @@ public abstract class AsyncTask { private Result postResult(Result result) { @SuppressWarnings("unchecked") - Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT, + Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult(this, result)); message.sendToTarget(); return result; @@ -620,7 +624,7 @@ public abstract class AsyncTask { */ protected final void publishProgress(Progress... values) { if (!isCancelled()) { - sHandler.obtainMessage(MESSAGE_POST_PROGRESS, + getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult(this, values)).sendToTarget(); } } @@ -635,10 +639,14 @@ public abstract class AsyncTask { } private static class InternalHandler extends Handler { + public InternalHandler() { + super(Looper.getMainLooper()); + } + @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { - AsyncTaskResult result = (AsyncTaskResult) msg.obj; + AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result