private boolean mLoading;
private boolean mVisible;
private boolean mFlingingFast;
+ private boolean mTaskLoadQueueIdle;
public HighResThumbnailLoader(SystemServicesProxy ssp, Looper looper) {
mMainThreadHandler = new Handler(looper);
updateLoading();
}
+ /**
+ * Sets whether the other task load queue is idling. Avoid double-loading bitmaps by not
+ * starting this queue until the other queue is idling.
+ */
+ public void setTaskLoadQueueIdle(boolean idle) {
+ mTaskLoadQueueIdle = idle;
+ updateLoading();
+ }
+
@VisibleForTesting
boolean isLoading() {
return mLoading;
}
private void updateLoading() {
- setLoading(mVisible && !mFlingingFast);
+ setLoading(mVisible && !mFlingingFast && mTaskLoadQueueIdle);
}
private void setLoading(boolean loading) {
* A Task load queue
*/
class TaskResourceLoadQueue {
+
ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>();
/** Adds a new task to the load queue */
boolean mCancelled;
boolean mWaitingOnLoadQueue;
+ private final OnIdleChangedListener mOnIdleChangedListener;
+
/** Constructor, creates a new loading thread that loads task resources in the background */
public BackgroundTaskLoader(TaskResourceLoadQueue loadQueue,
TaskKeyLruCache<Drawable> iconCache, Bitmap defaultThumbnail,
- BitmapDrawable defaultIcon) {
+ BitmapDrawable defaultIcon, OnIdleChangedListener onIdleChangedListener) {
mLoadQueue = loadQueue;
mIconCache = iconCache;
mDefaultThumbnail = defaultThumbnail;
mDefaultIcon = defaultIcon;
mMainThreadHandler = new Handler();
+ mOnIdleChangedListener = onIdleChangedListener;
mLoadThread = new HandlerThread("Recents-TaskResourceLoader",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
mLoadThread.start();
synchronized(mLoadQueue) {
try {
mWaitingOnLoadQueue = true;
+ mMainThreadHandler.post(
+ () -> mOnIdleChangedListener.onIdleChanged(true));
mLoadQueue.wait();
+ mMainThreadHandler.post(
+ () -> mOnIdleChangedListener.onIdleChanged(false));
mWaitingOnLoadQueue = false;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
+
+ interface OnIdleChangedListener {
+ void onIdleChanged(boolean idle);
+ }
}
/**
// Initialize the proxy, cache and loaders
int numRecentTasks = ActivityManager.getMaxRecentTasksStatic();
+ mHighResThumbnailLoader = new HighResThumbnailLoader(Recents.getSystemServices(),
+ Looper.getMainLooper());
mLoadQueue = new TaskResourceLoadQueue();
mIconCache = new TaskKeyLruCache<>(iconCacheSize, mClearActivityInfoOnEviction);
mActivityLabelCache = new TaskKeyLruCache<>(numRecentTasks, mClearActivityInfoOnEviction);
mContentDescriptionCache = new TaskKeyLruCache<>(numRecentTasks,
mClearActivityInfoOnEviction);
mActivityInfoCache = new LruCache(numRecentTasks);
- mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mDefaultThumbnail, mDefaultIcon);
- mHighResThumbnailLoader = new HighResThumbnailLoader(Recents.getSystemServices(),
- Looper.getMainLooper());
+ mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mDefaultThumbnail, mDefaultIcon,
+ mHighResThumbnailLoader::setTaskLoadQueueIdle);
}
/** Returns the size of the app icon cache. */
mTempCache.evictAll();
if (!opts.onlyLoadForCache) {
mNumVisibleTasksLoaded = opts.numVisibleTasks;
-
- // Start the loader
- mLoader.start(context);
}
}
}
/**
+ * Starts loading tasks.
+ */
+ public void startLoader(Context ctx) {
+ mLoader.start(ctx);
+ }
+
+ /**
* Stops the task loader and clears all queued, pending task loads.
*/
private void stopLoader() {