From d33860f2cc027b91dd09cc38ddd0e37878ba6c69 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 23 Apr 2015 16:02:20 -0700 Subject: Clearing all pending runnables when Launcher is destroyed. Change-Id: I00596c11116b5579c1f013b268b6c0b5239f0aa7 --- src/com/android/launcher3/DeferredHandler.java | 47 +++++------------------- src/com/android/launcher3/Launcher.java | 6 ---- src/com/android/launcher3/LauncherModel.java | 49 ++++++++++---------------- 3 files changed, 28 insertions(+), 74 deletions(-) diff --git a/src/com/android/launcher3/DeferredHandler.java b/src/com/android/launcher3/DeferredHandler.java index eb7c26a28..a43ab6723 100644 --- a/src/com/android/launcher3/DeferredHandler.java +++ b/src/com/android/launcher3/DeferredHandler.java @@ -20,12 +20,10 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.MessageQueue; -import android.util.Pair; import com.android.launcher3.util.Thunk; import java.util.LinkedList; -import java.util.ListIterator; /** * Queue of things to run on a looper thread. Items posted with {@link #post} will not @@ -35,20 +33,18 @@ import java.util.ListIterator; * This class is fifo. */ public class DeferredHandler { - @Thunk LinkedList> mQueue = new LinkedList>(); + @Thunk LinkedList mQueue = new LinkedList<>(); private MessageQueue mMessageQueue = Looper.myQueue(); private Impl mHandler = new Impl(); @Thunk class Impl extends Handler implements MessageQueue.IdleHandler { public void handleMessage(Message msg) { - Pair p; Runnable r; synchronized (mQueue) { if (mQueue.size() == 0) { return; } - p = mQueue.removeFirst(); - r = p.first; + r = mQueue.removeFirst(); } r.run(); synchronized (mQueue) { @@ -79,11 +75,8 @@ public class DeferredHandler { /** Schedule runnable to run after everything that's on the queue right now. */ public void post(Runnable runnable) { - post(runnable, 0); - } - public void post(Runnable runnable, int type) { synchronized (mQueue) { - mQueue.add(new Pair(runnable, type)); + mQueue.add(runnable); if (mQueue.size() == 1) { scheduleNextLocked(); } @@ -92,31 +85,10 @@ public class DeferredHandler { /** Schedule runnable to run when the queue goes idle. */ public void postIdle(final Runnable runnable) { - postIdle(runnable, 0); - } - public void postIdle(final Runnable runnable, int type) { - post(new IdleRunnable(runnable), type); - } - - public void cancelRunnable(Runnable runnable) { - synchronized (mQueue) { - while (mQueue.remove(runnable)) { } - } - } - public void cancelAllRunnablesOfType(int type) { - synchronized (mQueue) { - ListIterator> iter = mQueue.listIterator(); - Pair p; - while (iter.hasNext()) { - p = iter.next(); - if (p.second == type) { - iter.remove(); - } - } - } + post(new IdleRunnable(runnable)); } - public void cancel() { + public void cancelAll() { synchronized (mQueue) { mQueue.clear(); } @@ -124,20 +96,19 @@ public class DeferredHandler { /** Runs all queued Runnables from the calling thread. */ public void flush() { - LinkedList> queue = new LinkedList>(); + LinkedList queue = new LinkedList<>(); synchronized (mQueue) { queue.addAll(mQueue); mQueue.clear(); } - for (Pair p : queue) { - p.first.run(); + for (Runnable r : queue) { + r.run(); } } void scheduleNextLocked() { if (mQueue.size() > 0) { - Pair p = mQueue.getFirst(); - Runnable peek = p.first; + Runnable peek = mQueue.getFirst(); if (peek instanceof IdleRunnable) { mMessageQueue.addIdleHandler(mHandler); } else { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 20844777f..7220e0258 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2047,12 +2047,6 @@ public class Launcher extends Activity TextKeyListener.getInstance().release(); - // Disconnect any of the callbacks and drawables associated with ItemInfos on the workspace - // to prevent leaking Launcher activities on orientation change. - if (mModel != null) { - mModel.unbindItemInfosAndClearQueuedBindRunnables(); - } - getContentResolver().unregisterContentObserver(mWidgetObserver); unregisterReceiver(mCloseSystemDialogsReceiver); diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 5a65cab82..a5703a262 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -28,7 +28,6 @@ import android.content.Context; import android.content.Intent; import android.content.Intent.ShortcutIconResource; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; @@ -109,11 +108,6 @@ public class LauncherModel extends BroadcastReceiver @Thunk LoaderTask mLoaderTask; @Thunk boolean mIsLoaderTaskRunning; - // Specific runnable types that are run on the main thread deferred handler, this allows us to - // clear all queued binding runnables when the Launcher activity is destroyed. - private static final int MAIN_THREAD_NORMAL_RUNNABLE = 0; - private static final int MAIN_THREAD_BINDING_RUNNABLE = 1; - private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings"; @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); @@ -256,9 +250,6 @@ public class LauncherModel extends BroadcastReceiver /** Runs the specified runnable immediately if called from the main thread, otherwise it is * posted on the main thread handler. */ @Thunk void runOnMainThread(Runnable r) { - runOnMainThread(r, 0); - } - @Thunk void runOnMainThread(Runnable r, int type) { if (sWorkerThread.getThreadId() == Process.myTid()) { // If we are on the worker thread, post onto the main handler mHandler.post(r); @@ -679,7 +670,7 @@ public class LauncherModel extends BroadcastReceiver runOnWorkerThread(r); } - public void unbindItemInfosAndClearQueuedBindRunnables() { + private void unbindItemInfosAndClearQueuedBindRunnables() { if (sWorkerThread.getThreadId() == Process.myTid()) { throw new RuntimeException("Expected unbindLauncherItemInfos() to be called from the " + "main thread"); @@ -689,8 +680,9 @@ public class LauncherModel extends BroadcastReceiver synchronized (mDeferredBindRunnables) { mDeferredBindRunnables.clear(); } - // Remove any queued bind runnables - mHandler.cancelAllRunnablesOfType(MAIN_THREAD_BINDING_RUNNABLE); + + // Remove any queued UI runnables + mHandler.cancelAll(); // Unbind all the workspace items unbindWorkspaceItemsOnMainThread(); } @@ -699,19 +691,15 @@ public class LauncherModel extends BroadcastReceiver void unbindWorkspaceItemsOnMainThread() { // Ensure that we don't use the same workspace items data structure on the main thread // by making a copy of workspace items first. - final ArrayList tmpWorkspaceItems = new ArrayList(); - final ArrayList tmpAppWidgets = new ArrayList(); + final ArrayList tmpItems = new ArrayList(); synchronized (sBgLock) { - tmpWorkspaceItems.addAll(sBgWorkspaceItems); - tmpAppWidgets.addAll(sBgAppWidgets); + tmpItems.addAll(sBgWorkspaceItems); + tmpItems.addAll(sBgAppWidgets); } Runnable r = new Runnable() { @Override public void run() { - for (ItemInfo item : tmpWorkspaceItems) { - item.unbind(); - } - for (ItemInfo item : tmpAppWidgets) { + for (ItemInfo item : tmpItems) { item.unbind(); } } @@ -1297,6 +1285,9 @@ public class LauncherModel extends BroadcastReceiver */ public void initialize(Callbacks callbacks) { synchronized (mLock) { + // Disconnect any of the callbacks and drawables associated with ItemInfos on the + // workspace to prevent leaking Launcher activities on orientation change. + unbindItemInfosAndClearQueuedBindRunnables(); mCallbacks = new WeakReference(callbacks); } } @@ -1486,7 +1477,7 @@ public class LauncherModel extends BroadcastReceiver mDeferredBindRunnables.clear(); } for (final Runnable r : deferredBindRunnables) { - mHandler.post(r, MAIN_THREAD_BINDING_RUNNABLE); + mHandler.post(r); } } } @@ -2619,7 +2610,7 @@ public class LauncherModel extends BroadcastReceiver } } }; - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } private void bindWorkspaceItems(final Callbacks oldCallbacks, @@ -2650,7 +2641,7 @@ public class LauncherModel extends BroadcastReceiver deferredBindRunnables.add(r); } } else { - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } } @@ -2669,7 +2660,7 @@ public class LauncherModel extends BroadcastReceiver deferredBindRunnables.add(r); } } else { - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } } @@ -2688,7 +2679,7 @@ public class LauncherModel extends BroadcastReceiver if (postOnMainThread) { deferredBindRunnables.add(r); } else { - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } } } @@ -2768,7 +2759,7 @@ public class LauncherModel extends BroadcastReceiver } } }; - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); bindWorkspaceScreens(oldCallbacks, orderedScreenIds); @@ -2784,7 +2775,7 @@ public class LauncherModel extends BroadcastReceiver } } }; - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } // Load all the remaining pages (if we are loading synchronously, we want to defer this @@ -2817,7 +2808,7 @@ public class LauncherModel extends BroadcastReceiver mDeferredBindRunnables.add(r); } } else { - runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); + runOnMainThread(r); } } @@ -2888,8 +2879,6 @@ public class LauncherModel extends BroadcastReceiver // Clear the list of apps mBgAllAppsList.clear(); - SharedPreferences prefs = mContext.getSharedPreferences( - LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); for (UserHandleCompat user : profiles) { // Query for the set of apps final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; -- cgit v1.2.3