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.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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
|
* 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 static final String EXTRA_PACKAGE_INFO = "org.fdroid.fdroid.data.extra.PACKAGE_INFO";
|
||||||
|
|
||||||
|
private ScheduledExecutorService worker;
|
||||||
|
private boolean notifyChangeNeedsSending;
|
||||||
|
|
||||||
public InstalledAppProviderService() {
|
public InstalledAppProviderService() {
|
||||||
super("InstalledAppProviderService");
|
super("InstalledAppProviderService");
|
||||||
}
|
}
|
||||||
@ -125,10 +131,7 @@ public class InstalledAppProviderService extends IntentService {
|
|||||||
} else if (ACTION_DELETE.equals(action)) {
|
} else if (ACTION_DELETE.equals(action)) {
|
||||||
deleteAppFromDb(this, packageName);
|
deleteAppFromDb(this, packageName);
|
||||||
}
|
}
|
||||||
|
notifyChange();
|
||||||
Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views).");
|
|
||||||
getContentResolver().notifyChange(AppProvider.getContentUri(), null);
|
|
||||||
getContentResolver().notifyChange(ApkProvider.getContentUri(), null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,4 +163,32 @@ public class InstalledAppProviderService extends IntentService {
|
|||||||
Uri uri = InstalledAppProvider.getAppUri(packageName);
|
Uri uri = InstalledAppProvider.getAppUri(packageName);
|
||||||
context.getContentResolver().delete(uri, null, null);
|
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