summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoe Onorato <joeo@android.com>2010-06-08 11:58:38 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-06-08 11:58:38 -0700
commitacc017320a798ae7dcdf7eeeee2963bff7a7697c (patch)
treeacad1cd727926d44ea5e92325e70b23f5d00fab3 /src
parent31333b9716023220a377d6482f60140e2f8f2524 (diff)
parentcc67f476c01ee6a7d593fa67f80392c6793432d7 (diff)
downloadandroid_packages_apps_Trebuchet-acc017320a798ae7dcdf7eeeee2963bff7a7697c.tar.gz
android_packages_apps_Trebuchet-acc017320a798ae7dcdf7eeeee2963bff7a7697c.tar.bz2
android_packages_apps_Trebuchet-acc017320a798ae7dcdf7eeeee2963bff7a7697c.zip
am cc67f476: Improve launcher loading performance by only doing re-binds.
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher2/Launcher.java9
-rw-r--r--src/com/android/launcher2/LauncherApplication.java2
-rw-r--r--src/com/android/launcher2/LauncherModel.java165
3 files changed, 82 insertions, 94 deletions
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 62aaa8be6..13a39a3a3 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -92,7 +92,7 @@ import com.android.launcher.R;
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
static final String TAG = "Launcher";
- static final boolean LOGD = true;
+ static final boolean LOGD = false;
static final boolean PROFILE_STARTUP = false;
static final boolean DEBUG_WIDGETS = false;
@@ -247,11 +247,6 @@ public final class Launcher extends Activity
android.os.Debug.stopMethodTracing();
}
- // We have a new AllAppsView, we need to re-bind everything, and it could have
- // changed in our absence.
- mModel.setAllAppsDirty();
- mModel.setWorkspaceDirty();
-
if (!mRestoring) {
mModel.startLoader(this, true);
}
@@ -1856,7 +1851,6 @@ public final class Launcher extends Activity
if (mWorkspaceLoading) {
lockAllApps();
- mModel.setWorkspaceDirty();
mModel.startLoader(Launcher.this, false);
} else {
final FolderIcon folderIcon = (FolderIcon)
@@ -1866,7 +1860,6 @@ public final class Launcher extends Activity
getWorkspace().requestLayout();
} else {
lockAllApps();
- mModel.setWorkspaceDirty();
mWorkspaceLoading = true;
mModel.startLoader(Launcher.this, false);
}
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index be448a891..eda92d999 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -73,8 +73,6 @@ public class LauncherApplication extends Application {
private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
- // TODO: lockAllApps();
- mModel.setWorkspaceDirty();
mModel.startLoader(LauncherApplication.this, false);
}
};
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();