diff options
author | Joe Onorato <joeo@android.com> | 2010-06-08 10:54:30 -0700 |
---|---|---|
committer | Joe Onorato <joeo@android.com> | 2010-06-08 11:32:28 -0700 |
commit | cc67f476c01ee6a7d593fa67f80392c6793432d7 (patch) | |
tree | ad435ddee366c2d4ba779ea835fa89b11aeaaa6a /src/com/android/launcher2/LauncherModel.java | |
parent | 843e860e8ebab96ff70988f2829fac38afd9d937 (diff) | |
download | android_packages_apps_Trebuchet-cc67f476c01ee6a7d593fa67f80392c6793432d7.tar.gz android_packages_apps_Trebuchet-cc67f476c01ee6a7d593fa67f80392c6793432d7.tar.bz2 android_packages_apps_Trebuchet-cc67f476c01ee6a7d593fa67f80392c6793432d7.zip |
Improve launcher loading performance by only doing re-binds.
This always reloads the workspace, because I think it's a less risky change and that only adds
~100ms.
Change-Id: I215b1f741f022e47ce06e78b9cfdd9967a8f1b9d
Diffstat (limited to 'src/com/android/launcher2/LauncherModel.java')
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 165 |
1 files changed, 81 insertions, 84 deletions
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 96ceb747f..ce26f37a2 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -71,6 +71,12 @@ public class LauncherModel extends BroadcastReceiver { private DeferredHandler mHandler = new DeferredHandler(); private Loader mLoader = new Loader(); + // We start off with everything not loaded. After that, we assume that + // our monitoring of the package manager provides all updates and we never + // need to do a requery. These are only ever touched from the loader thread. + private boolean mWorkspaceLoaded; + private boolean mAllAppsLoaded; + private boolean mBeforeFirstLoad = true; // only access this from main thread private WeakReference<Callbacks> mCallbacks; @@ -287,17 +293,6 @@ public class LauncherModel extends BroadcastReceiver { } /** - * We pick up most of the changes to all apps. - */ - public void setAllAppsDirty() { - mLoader.setAllAppsDirty(); - } - - public void setWorkspaceDirty() { - mLoader.setWorkspaceDirty(); - } - - /** * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and * ACTION_PACKAGE_CHANGED. */ @@ -398,8 +393,9 @@ public class LauncherModel extends BroadcastReceiver { if (packages == null || packages.length == 0) { return; } - setAllAppsDirty(); - setWorkspaceDirty(); + synchronized (this) { + mAllAppsLoaded = mWorkspaceLoaded = false; + } startLoader(context, false); } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { String packages[] = intent.getStringArrayExtra( @@ -407,8 +403,9 @@ public class LauncherModel extends BroadcastReceiver { if (packages == null || packages.length == 0) { return; } - setAllAppsDirty(); - setWorkspaceDirty(); + synchronized (this) { + mAllAppsLoaded = mWorkspaceLoaded = false; + } startLoader(context, false); } } @@ -420,12 +417,6 @@ public class LauncherModel extends BroadcastReceiver { private LoaderThread mLoaderThread; - private int mLastWorkspaceSeq = 0; - private int mWorkspaceSeq = 1; - - private int mLastAllAppsSeq = 0; - private int mAllAppsSeq = 1; - final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>(); final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>(); final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>(); @@ -466,18 +457,6 @@ public class LauncherModel extends BroadcastReceiver { } } - public void setWorkspaceDirty() { - synchronized (mLock) { - mWorkspaceSeq++; - } - } - - public void setAllAppsDirty() { - synchronized (mLock) { - mAllAppsSeq++; - } - } - /** * Runnable for the thread that loads the contents of the launcher: * - workspace icons @@ -524,60 +503,33 @@ public class LauncherModel extends BroadcastReceiver { } private void loadAndBindWorkspace() { - // Load the workspace only if it's dirty. - int workspaceSeq; - boolean workspaceDirty; - synchronized (mLock) { - workspaceSeq = mWorkspaceSeq; - workspaceDirty = mWorkspaceSeq != mLastWorkspaceSeq; + // Load the workspace + + // Other other threads can unset mWorkspaceLoaded, so atomically set it, + // and then if they unset it, or we unset it because of mStopped, it will + // be unset. + boolean loaded; + synchronized (this) { + loaded = mWorkspaceLoaded; + mWorkspaceLoaded = true; } - if (workspaceDirty) { + + // For now, just always reload the workspace. It's ~100 ms vs. the + // binding which takes many hundreds of ms. + // We can reconsider. + if (DEBUG_LOADERS) Log.d(TAG, "loadAndBindWorkspace loaded=" + loaded); + if (true || !loaded) { loadWorkspace(); - } - synchronized (mLock) { - // If we're not stopped, and nobody has incremented mWorkspaceSeq. if (mStopped) { - if (PROFILE_LOADERS) { - android.os.Debug.stopMethodTracing(); - } - + mWorkspaceLoaded = false; return; } - if (workspaceSeq == mWorkspaceSeq) { - mLastWorkspaceSeq = mWorkspaceSeq; - } } // Bind the workspace bindWorkspace(); } - private void loadAndBindAllAppsIfDirty() { - // Load all apps if they're dirty - int allAppsSeq; - boolean allAppsDirty; - synchronized (mLock) { - allAppsSeq = mAllAppsSeq; - allAppsDirty = mAllAppsSeq != mLastAllAppsSeq; - if (DEBUG_LOADERS) { - Log.d(TAG, "mAllAppsSeq=" + mAllAppsSeq - + " mLastAllAppsSeq=" + mLastAllAppsSeq + " allAppsDirty"); - } - } - if (allAppsDirty) { - loadAndBindAllApps(); - } - synchronized (mLock) { - // If we're not stopped, and nobody has incremented mAllAppsSeq. - if (mStopped) { - return; - } - if (allAppsSeq == mAllAppsSeq) { - mLastAllAppsSeq = mAllAppsSeq; - } - } - } - private void waitForIdle() { // Wait until the either we're stopped or the other threads are done. // This way we don't start loading all apps until the workspace has settled @@ -637,7 +589,7 @@ public class LauncherModel extends BroadcastReceiver { loadAndBindWorkspace(); } else { if (DEBUG_LOADERS) Log.d(TAG, "step 1: special: loading all apps"); - loadAndBindAllAppsIfDirty(); + loadAndBindAllApps(); } // Whew! Hard work done. @@ -650,7 +602,7 @@ public class LauncherModel extends BroadcastReceiver { // second step if (loadWorkspaceFirst) { if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); - loadAndBindAllAppsIfDirty(); + loadAndBindAllApps(); } else { if (DEBUG_LOADERS) Log.d(TAG, "step 2: special: loading workspace"); loadAndBindWorkspace(); @@ -671,7 +623,7 @@ public class LauncherModel extends BroadcastReceiver { } // Trigger a gc to try to clean up after the stuff is done, since the - // renderscript allocations aren't charge to the java heap. + // renderscript allocations aren't charged to the java heap. mHandler.post(new Runnable() { public void run() { System.gc(); @@ -1133,6 +1085,55 @@ public class LauncherModel extends BroadcastReceiver { } private void loadAndBindAllApps() { + // Other other threads can unset mAllAppsLoaded, so atomically set it, + // and then if they unset it, or we unset it because of mStopped, it will + // be unset. + boolean loaded; + synchronized (this) { + loaded = mAllAppsLoaded; + mAllAppsLoaded = true; + } + + if (DEBUG_LOADERS) Log.d(TAG, "loadAndBindAllApps loaded=" + loaded); + if (!loaded) { + loadAllAppsByBatch(); + if (mStopped) { + mAllAppsLoaded = false; + return; + } + } else { + onlyBindAllApps(); + } + } + + private void onlyBindAllApps() { + final Callbacks oldCallbacks = mCallbacks.get(); + if (oldCallbacks == null) { + // This launcher has exited and nobody bothered to tell us. Just bail. + Log.w(TAG, "LoaderThread running with no launcher (onlyBindAllApps)"); + return; + } + + // shallow copy + final ArrayList<ApplicationInfo> list + = (ArrayList<ApplicationInfo>)mAllAppsList.data.clone(); + mHandler.post(new Runnable() { + public void run() { + final long t = SystemClock.uptimeMillis(); + final Callbacks callbacks = tryGetCallbacks(oldCallbacks); + if (callbacks != null) { + callbacks.bindAllApplications(list); + } + if (DEBUG_LOADERS) { + Log.d(TAG, "bound all " + list.size() + " apps from cache in " + + (SystemClock.uptimeMillis()-t) + "ms"); + } + } + }); + + } + + private void loadAllAppsByBatch() { final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; // Don't use these two variables in any of the callback runnables. @@ -1140,7 +1141,7 @@ public class LauncherModel extends BroadcastReceiver { final Callbacks oldCallbacks = mCallbacks.get(); if (oldCallbacks == null) { // This launcher has exited and nobody bothered to tell us. Just bail. - Log.w(TAG, "LoaderThread running with no launcher (loadAndBindAllApps)"); + Log.w(TAG, "LoaderThread running with no launcher (loadAllAppsByBatch)"); return; } @@ -1262,10 +1263,6 @@ public class LauncherModel extends BroadcastReceiver { } public void dumpState() { - Log.d(TAG, "mLoader.mLastWorkspaceSeq=" + mLoader.mLastWorkspaceSeq); - Log.d(TAG, "mLoader.mWorkspaceSeq=" + mLoader.mWorkspaceSeq); - Log.d(TAG, "mLoader.mLastAllAppsSeq=" + mLoader.mLastAllAppsSeq); - Log.d(TAG, "mLoader.mAllAppsSeq=" + mLoader.mAllAppsSeq); Log.d(TAG, "mLoader.mItems size=" + mLoader.mItems.size()); if (mLoaderThread != null) { mLoaderThread.dumpState(); |