OSDN Git Service

WidgetTray performance improvement (less sorting): Part 1
authorHyunyoung Song <hyunyoungs@google.com>
Mon, 4 May 2015 23:28:20 +0000 (16:28 -0700)
committerHyunyoung Song <hyunyoungs@google.com>
Mon, 4 May 2015 23:28:20 +0000 (16:28 -0700)
- No longer return sorted list from the package manager since, the only
time the widget list requires to be sorted is when recycler view renders
them.
- Made getWidgetsAndShortcuts private to guarantee that widgets are
being loaded in the worker thread.

Change-Id: I2c35973c1226e831514380dd38fc2f88b1b91d02

src/com/android/launcher3/Launcher.java
src/com/android/launcher3/LauncherModel.java
src/com/android/launcher3/WidgetPreviewLoader.java

index 2ef5d0a..efe27ad 100644 (file)
@@ -3584,14 +3584,13 @@ public class Launcher extends Activity
      * in onResume.
      *
      * This needs to be called from incoming places where resources might have been loaded
-     * while we are paused.  That is becaues the Configuration might be wrong
-     * when we're not running, and if it comes back to what it was when we
-     * were paused, we are not restarted.
+     * while the activity is paused. That is because the Configuration (e.g., rotation)  might be
+     * wrong when we're not running, and if the activity comes back to what the configuration was
+     * when we were paused, activity is not restarted.
      *
      * Implementation of the method from LauncherModel.Callbacks.
      *
-     * @return true if we are currently paused.  The caller might be able to
-     * skip some work in that case since we will come back again.
+     * @return {@code true} if we are currently paused. The caller might be able to skip some work
      */
     private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) {
         if (mPaused) {
@@ -4135,10 +4134,6 @@ public class Launcher extends Activity
         if (mAppsView != null) {
             mAppsView.setApps(apps);
         }
-        if (mWidgetsView != null) {
-            mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
-                    getPackageManager());
-        }
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.bindAllApplications(apps);
         }
@@ -4274,26 +4269,23 @@ public class Launcher extends Activity
         }
     }
 
-    /**
-     * A number of packages were updated.
-     */
     @Thunk ArrayList<Object> mWidgetsAndShortcuts;
     private Runnable mBindPackagesUpdatedRunnable = new Runnable() {
             public void run() {
-                bindPackagesUpdated(mWidgetsAndShortcuts);
-                mWidgetsAndShortcuts = null;
+                bindAllPackages(mWidgetsAndShortcuts);
             }
         };
 
-    public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
+    @Override
+    public void bindAllPackages(final ArrayList<Object> widgetsAndShortcuts) {
         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
             mWidgetsAndShortcuts = widgetsAndShortcuts;
             return;
         }
 
-        if (mWidgetsView != null) {
-            mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
-                    getPackageManager());
+        if (mWidgetsView != null && widgetsAndShortcuts != null) {
+            mWidgetsView.addWidgets(widgetsAndShortcuts, getPackageManager());
+            mWidgetsAndShortcuts = null;
         }
     }
 
index 97a2830..0624478 100644 (file)
@@ -197,7 +197,7 @@ public class LauncherModel extends BroadcastReceiver
         public void bindRestoreItemsChange(HashSet<ItemInfo> updates);
         public void bindComponentsRemoved(ArrayList<String> packageNames,
                         ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason);
-        public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
+        public void bindAllPackages(ArrayList<Object> widgetsAndShortcuts);
         public void bindSearchablesChanged();
         public boolean isAllAppsButtonRank(int rank);
         public void onPageBoundSynchronously(int page);
@@ -1594,9 +1594,6 @@ public class LauncherModel extends BroadcastReceiver
                 if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
                 loadAndBindAllApps();
 
-                // Remove entries for packages which changed while the launcher was dead.
-                LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews();
-
                 // Restore the default thread priority after we are done loading items
                 synchronized (mLock) {
                     android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
@@ -2865,6 +2862,7 @@ public class LauncherModel extends BroadcastReceiver
                     final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                     if (callbacks != null) {
                         callbacks.bindAllApplications(added);
+                        loadAndBindWidgetsAndShortcuts(mContext,callbacks);
                         if (DEBUG_LOADERS) {
                             Log.d(TAG, "bound " + added.size() + " apps in "
                                 + (SystemClock.uptimeMillis() - bindTime) + "ms");
@@ -3280,29 +3278,33 @@ public class LauncherModel extends BroadcastReceiver
         runOnWorkerThread(new Runnable(){
             @Override
             public void run() {
-                final ArrayList<Object> list =
-                        getSortedWidgetsAndShortcuts(context, true /* refresh */);
+                final ArrayList<Object> list = getWidgetsAndShortcuts(context, true /* refresh */);
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
                         Callbacks cb = getCallback();
                         if (callbacks == cb && cb != null) {
-                            callbacks.bindPackagesUpdated(list);
+                            callbacks.bindAllPackages(list);
                         }
                     }
                 });
+                // update the Widget entries inside DB on the worker thread.
+                LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(list);
             }
         });
     }
 
-    // Returns a list of ResolveInfos/AppWidgetInfos in sorted order
-    public static ArrayList<Object> getSortedWidgetsAndShortcuts(Context context, boolean refresh) {
+    /**
+     *  Returns a list of ResolveInfos/AppWidgetInfos.
+     *
+     *  @see #loadAndBindWidgetsAndShortcuts
+     */
+    private ArrayList<Object> getWidgetsAndShortcuts(Context context, boolean refresh) {
         PackageManager packageManager = context.getPackageManager();
         final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>();
         widgetsAndShortcuts.addAll(getWidgetProviders(context, refresh));
         Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
         widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0));
-        Collections.sort(widgetsAndShortcuts, new WidgetAndShortcutNameComparator(context));
         return widgetsAndShortcuts;
     }
 
index 412cbcd..93bfeaf 100644 (file)
@@ -24,6 +24,7 @@ import android.graphics.RectF;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
+import android.os.Process;
 import android.util.Log;
 import android.util.LongSparseArray;
 
@@ -34,6 +35,9 @@ import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.WidgetCell;
 
+import junit.framework.Assert;
+
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -202,11 +206,14 @@ public class WidgetPreviewLoader {
      *   2. Any preview for an absent package is removed
      * This ensures that we remove entries for packages which changed while the launcher was dead.
      */
-    public void removeObsoletePreviews() {
+    public void removeObsoletePreviews(ArrayList<Object> list) {
+        // This method should always be called from the worker thread.
+        Assert.assertTrue(LauncherModel.sWorkerThread.getThreadId() == Process.myTid());
+
         LongSparseArray<UserHandleCompat> userIdCache = new LongSparseArray<>();
         LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
 
-        for (Object obj : LauncherModel.getSortedWidgetsAndShortcuts(mContext, false)) {
+        for (Object obj : list) {
             final UserHandleCompat user;
             final String pkg;
             if (obj instanceof ResolveInfo) {