rate limit InstallApp install/delete notifications to 1000ms
InstallAppProviderService now processes install and delete events one at a time, where InstalledAppCacheUpdater made a batch of changes which it ran all at once. This means that InstallAppProviderService will send out a flood of notifications when first initializing, since it will index every single installed app and send a notification for each one. This makes the GUI lock up. This commit puts a rate limit on those notifications if they start coming fast. They are limited to one per second.
This commit is contained in:
parent
d734e584f6
commit
906a26414a
@ -14,6 +14,9 @@ import org.fdroid.fdroid.Utils;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Handles all updates to {@link InstalledAppProvider}, whether checking the contents
|
||||
@ -36,6 +39,9 @@ public class InstalledAppProviderService extends IntentService {
|
||||
|
||||
private static final String EXTRA_PACKAGE_INFO = "org.fdroid.fdroid.data.extra.PACKAGE_INFO";
|
||||
|
||||
private ScheduledExecutorService worker;
|
||||
private boolean notifyChangeNeedsSending;
|
||||
|
||||
public InstalledAppProviderService() {
|
||||
super("InstalledAppProviderService");
|
||||
}
|
||||
@ -125,10 +131,7 @@ public class InstalledAppProviderService extends IntentService {
|
||||
} else if (ACTION_DELETE.equals(action)) {
|
||||
deleteAppFromDb(this, packageName);
|
||||
}
|
||||
|
||||
Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views).");
|
||||
getContentResolver().notifyChange(AppProvider.getContentUri(), null);
|
||||
getContentResolver().notifyChange(ApkProvider.getContentUri(), null);
|
||||
notifyChange();
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,4 +163,32 @@ public class InstalledAppProviderService extends IntentService {
|
||||
Uri uri = InstalledAppProvider.getAppUri(packageName);
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This notifies the users of this {@link android.content.ContentProvider}
|
||||
* that the contents has changed. Since {@link Intent}s can come in slow
|
||||
* or fast, and this can trigger a lot of UI updates, the actual
|
||||
* notifications are rate limited to one per second.
|
||||
*/
|
||||
private void notifyChange() {
|
||||
notifyChangeNeedsSending = true;
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (notifyChangeNeedsSending) {
|
||||
Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views).");
|
||||
getContentResolver().notifyChange(AppProvider.getContentUri(), null);
|
||||
getContentResolver().notifyChange(ApkProvider.getContentUri(), null);
|
||||
notifyChangeNeedsSending = false;
|
||||
} else {
|
||||
worker.shutdown();
|
||||
worker = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (worker == null || worker.isShutdown()) {
|
||||
worker = Executors.newSingleThreadScheduledExecutor();
|
||||
worker.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user