diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java index 241356eee..175a78976 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java @@ -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); + } + } } \ No newline at end of file