Files
lawnchair/src/com/android/launcher2/DeferredHandler.java
Daniel Sandler dca661236c Batch loading of icons for AllApps.
AllAppsList now maintains <data> and <added> in sorted
order, to amortize the cost of sorting the apps list over
multiple batches.

Launcher boosts thread priority on first launch, but we now
reduce thread priority to normal after the main workspace
has been drawn but before all apps are loaded.

Experimental feature: a short delay is introduced between
batches to help free up the CPU (as well as to show that we
are indeed batching apps).

Bug: 2562420
Change-Id: I2035ec3e819b4e7993a80c6d03bfad3914c95a7a
2010-04-14 14:36:10 -04:00

114 lines
3.0 KiB
Java

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher2;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.util.Log;
import java.util.LinkedList;
/**
* Queue of things to run on a looper thread. Items posted with {@link #post} will not
* be actually enqued on the handler until after the last one has run, to keep from
* starving the thread.
*
* This class is fifo.
*/
public class DeferredHandler {
private LinkedList<Runnable> mQueue = new LinkedList();
private MessageQueue mMessageQueue = Looper.myQueue();
private Impl mHandler = new Impl();
private class Impl extends Handler implements MessageQueue.IdleHandler {
public void handleMessage(Message msg) {
Runnable r;
synchronized (mQueue) {
if (mQueue.size() == 0) {
return;
}
r = mQueue.removeFirst();
}
r.run();
synchronized (mQueue) {
scheduleNextLocked();
}
}
public boolean queueIdle() {
handleMessage(null);
return false;
}
}
private class IdleRunnable implements Runnable {
Runnable mRunnable;
IdleRunnable(Runnable r) {
mRunnable = r;
}
public void run() {
mRunnable.run();
}
}
public DeferredHandler() {
}
/** Schedule runnable to run after everything that's on the queue right now. */
public void post(Runnable runnable) {
synchronized (mQueue) {
mQueue.add(runnable);
if (mQueue.size() == 1) {
scheduleNextLocked();
}
}
}
/** Schedule runnable to run when the queue goes idle. */
public void postIdle(final Runnable runnable) {
post(new IdleRunnable(runnable));
}
public void cancelRunnable(Runnable runnable) {
synchronized (mQueue) {
while (mQueue.remove(runnable)) { }
}
}
public void cancel() {
synchronized (mQueue) {
mQueue.clear();
}
}
void scheduleNextLocked() {
if (mQueue.size() > 0) {
Runnable peek = mQueue.getFirst();
if (peek instanceof IdleRunnable) {
mMessageQueue.addIdleHandler(mHandler);
} else {
mHandler.sendEmptyMessage(1);
}
}
}
}