am dca66123: Batch loading of icons for AllApps.
This commit is contained in:
commit
e825010dc9
|
@ -50,6 +50,8 @@ public class AllApps2D
|
|||
|
||||
private static final String TAG = "Launcher.AllApps2D";
|
||||
|
||||
private static final int BATCH_SIZE = 6; // give us a few apps at a time
|
||||
|
||||
private Launcher mLauncher;
|
||||
private DragController mDragController;
|
||||
|
||||
|
@ -300,6 +302,10 @@ public class AllApps2D
|
|||
return -1;
|
||||
}
|
||||
|
||||
public int getAppBatchSize() {
|
||||
return BATCH_SIZE;
|
||||
}
|
||||
|
||||
public void dumpState() {
|
||||
ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList", mAllAppsList);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ public class AllApps3D extends RSSurfaceView
|
|||
private static final int SELECTION_ICONS = 1;
|
||||
private static final int SELECTION_HOME = 2;
|
||||
|
||||
private static final int BATCH_SIZE = 0; // give us all the apps at once
|
||||
|
||||
private Launcher mLauncher;
|
||||
private DragController mDragController;
|
||||
|
||||
|
@ -1593,6 +1595,10 @@ public class AllApps3D extends RSSurfaceView
|
|||
}
|
||||
}
|
||||
|
||||
public int getAppBatchSize() {
|
||||
return BATCH_SIZE;
|
||||
}
|
||||
|
||||
public void dumpState() {
|
||||
Log.d(TAG, "sRS=" + sRS);
|
||||
Log.d(TAG, "sRollo=" + sRollo);
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.content.pm.PackageManager;
|
|||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
@ -56,10 +57,17 @@ class AllAppsList {
|
|||
/**
|
||||
* Add the supplied ApplicationInfo objects to the list, and enqueue it into the
|
||||
* list to broadcast when notify() is called.
|
||||
*
|
||||
* Postcondition: data and added are sorted in order of LauncherModel.APP_NAME_COMPARATOR.
|
||||
*/
|
||||
public void add(ApplicationInfo info) {
|
||||
data.add(info);
|
||||
added.add(info);
|
||||
int pos = Collections.binarySearch(data, info, LauncherModel.APP_NAME_COMPARATOR);
|
||||
if (pos < 0) pos = -1 - pos;
|
||||
data.add(pos, info);
|
||||
|
||||
pos = Collections.binarySearch(added, info, LauncherModel.APP_NAME_COMPARATOR);
|
||||
if (pos < 0) pos = -1 - pos;
|
||||
added.add(pos, info);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
@ -86,9 +94,7 @@ class AllAppsList {
|
|||
|
||||
if (matches.size() > 0) {
|
||||
for (ResolveInfo info : matches) {
|
||||
ApplicationInfo item = new ApplicationInfo(info, mIconCache);
|
||||
data.add(item);
|
||||
added.add(item);
|
||||
add(new ApplicationInfo(info, mIconCache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,9 +145,7 @@ class AllAppsList {
|
|||
info.activityInfo.applicationInfo.packageName,
|
||||
info.activityInfo.name);
|
||||
if (applicationInfo == null) {
|
||||
applicationInfo = new ApplicationInfo(info, mIconCache);
|
||||
data.add(applicationInfo);
|
||||
added.add(applicationInfo);
|
||||
add(new ApplicationInfo(info, mIconCache));
|
||||
} else {
|
||||
mIconCache.remove(applicationInfo.componentName);
|
||||
mIconCache.getTitleAndIcon(applicationInfo, info);
|
||||
|
|
|
@ -40,8 +40,10 @@ public interface AllAppsView {
|
|||
public void removeApps(ArrayList<ApplicationInfo> list);
|
||||
|
||||
public void updateApps(ArrayList<ApplicationInfo> list);
|
||||
|
||||
public int getAppBatchSize();
|
||||
|
||||
public void dumpState();
|
||||
|
||||
|
||||
public void surrender();
|
||||
}
|
||||
|
|
|
@ -87,6 +87,12 @@ public class DeferredHandler {
|
|||
post(new IdleRunnable(runnable));
|
||||
}
|
||||
|
||||
public void cancelRunnable(Runnable runnable) {
|
||||
synchronized (mQueue) {
|
||||
while (mQueue.remove(runnable)) { }
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
synchronized (mQueue) {
|
||||
mQueue.clear();
|
||||
|
|
|
@ -2085,6 +2085,15 @@ public final class Launcher extends Activity
|
|||
mAllAppsGrid.removeApps(apps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out how many apps we should send to the grid at a time.
|
||||
*
|
||||
* Implementation of the method from LauncherModel.Callbacks.
|
||||
*/
|
||||
public int getAppBatchSize() {
|
||||
return mAllAppsGrid.getAppBatchSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out out state for debugging.
|
||||
*/
|
||||
|
|
|
@ -62,6 +62,8 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
static final boolean DEBUG_LOADERS = false;
|
||||
static final String TAG = "Launcher.Model";
|
||||
|
||||
final int ALL_APPS_LOAD_DELAY = 150; // ms
|
||||
|
||||
private final LauncherApplication mApp;
|
||||
private final Object mLock = new Object();
|
||||
private DeferredHandler mHandler = new DeferredHandler();
|
||||
|
@ -86,6 +88,7 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
public void bindAppsAdded(ArrayList<ApplicationInfo> apps);
|
||||
public void bindAppsUpdated(ArrayList<ApplicationInfo> apps);
|
||||
public void bindAppsRemoved(ArrayList<ApplicationInfo> apps);
|
||||
public int getAppBatchSize();
|
||||
}
|
||||
|
||||
LauncherModel(LauncherApplication app, IconCache iconCache) {
|
||||
|
@ -575,6 +578,13 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
// Whew! Hard work done.
|
||||
synchronized (mLock) {
|
||||
if (mIsLaunching) {
|
||||
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
// Load all apps if they're dirty
|
||||
int allAppsSeq;
|
||||
boolean allAppsDirty;
|
||||
|
@ -587,7 +597,7 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
if (allAppsDirty) {
|
||||
loadAllApps();
|
||||
loadAndBindAllApps();
|
||||
}
|
||||
synchronized (mLock) {
|
||||
// If we're not stopped, and nobody has incremented mAllAppsSeq.
|
||||
|
@ -599,11 +609,6 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
// Bind all apps
|
||||
if (allAppsDirty) {
|
||||
bindAllApps();
|
||||
}
|
||||
|
||||
// Clear out this reference, otherwise we end up holding it until all of the
|
||||
// callback runnables are done.
|
||||
mContext = null;
|
||||
|
@ -1014,7 +1019,9 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
});
|
||||
}
|
||||
|
||||
private void loadAllApps() {
|
||||
private void loadAndBindAllApps() {
|
||||
final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
|
||||
|
||||
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
|
@ -1026,53 +1033,79 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
final PackageManager packageManager = mContext.getPackageManager();
|
||||
final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
|
||||
|
||||
int N;
|
||||
int batchSize = callbacks.getAppBatchSize();
|
||||
|
||||
synchronized (mLock) {
|
||||
mBeforeFirstLoad = false;
|
||||
|
||||
mAllAppsList.clear();
|
||||
if (apps != null) {
|
||||
long t = SystemClock.uptimeMillis();
|
||||
if (apps == null) return;
|
||||
N = apps.size();
|
||||
if (batchSize <= 0)
|
||||
batchSize = N;
|
||||
}
|
||||
|
||||
int N = apps.size();
|
||||
for (int i=0; i<N && !mStopped; i++) {
|
||||
int i=0;
|
||||
while (i < N && !mStopped) {
|
||||
synchronized (mLock) {
|
||||
final long t2 = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
|
||||
|
||||
for (int j=0; i<N && j<batchSize; j++) {
|
||||
// This builds the icon bitmaps.
|
||||
mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache));
|
||||
i++;
|
||||
}
|
||||
// re-sort before binding this batch to the grid
|
||||
Collections.sort(mAllAppsList.data, APP_NAME_COMPARATOR);
|
||||
Collections.sort(mAllAppsList.added, APP_NAME_COMPARATOR);
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "cached app icons in "
|
||||
+ (SystemClock.uptimeMillis()-t) + "ms");
|
||||
Log.d(TAG, "batch of " + batchSize + " icons processed in "
|
||||
+ (SystemClock.uptimeMillis()-t2) + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
mHandler.post(bindAllAppsTask);
|
||||
|
||||
if (ALL_APPS_LOAD_DELAY > 0) {
|
||||
try {
|
||||
Thread.sleep(ALL_APPS_LOAD_DELAY);
|
||||
} catch (InterruptedException exc) { }
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "cached all " + N + " apps in "
|
||||
+ (SystemClock.uptimeMillis()-t) + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
private void bindAllApps() {
|
||||
synchronized (mLock) {
|
||||
final ArrayList<ApplicationInfo> results
|
||||
= (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
|
||||
// We're adding this now, so clear out this so we don't re-send them.
|
||||
mAllAppsList.added = new ArrayList<ApplicationInfo>();
|
||||
final Callbacks old = mCallbacks.get();
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
final long t = SystemClock.uptimeMillis();
|
||||
final int count = results.size();
|
||||
final Runnable bindAllAppsTask = new Runnable() {
|
||||
public void run() {
|
||||
final long t = SystemClock.uptimeMillis();
|
||||
int count = 0;
|
||||
Callbacks callbacks = null;
|
||||
ArrayList<ApplicationInfo> results = null;
|
||||
synchronized (mLock) {
|
||||
mHandler.cancelRunnable(this);
|
||||
|
||||
Callbacks callbacks = tryGetCallbacks(old);
|
||||
if (callbacks != null) {
|
||||
callbacks.bindAllApplications(results);
|
||||
}
|
||||
results = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
|
||||
// We're adding this now, so clear out this so we don't re-send them.
|
||||
mAllAppsList.added = new ArrayList<ApplicationInfo>();
|
||||
count = results.size();
|
||||
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "bound app " + count + " icons in "
|
||||
+ (SystemClock.uptimeMillis() - t) + "ms");
|
||||
}
|
||||
}
|
||||
});
|
||||
callbacks = tryGetCallbacks(mCallbacks.get());
|
||||
}
|
||||
|
||||
if (callbacks != null && count > 0) {
|
||||
callbacks.bindAllApplications(results);
|
||||
}
|
||||
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "bound " + count + " apps in "
|
||||
+ (SystemClock.uptimeMillis() - t) + "ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void dumpState() {
|
||||
Log.d(TAG, "mLoader.mLoaderThread.mContext=" + mContext);
|
||||
|
|
Loading…
Reference in New Issue