do not update InstalledAppProvider if already current
This adds a check of whether the database has the current APK in it, based on PackageInfo's lastUpdateTime field. This avoids recalculating the hash of the whole APK, which is quite time and resource intensive.
This commit is contained in:
parent
90467bf8bf
commit
748352e5a1
@ -27,12 +27,12 @@ public class InstalledAppProvider extends FDroidProvider {
|
||||
public static class Helper {
|
||||
|
||||
/**
|
||||
* @return The keys are the app ids (package names), and their corresponding values are
|
||||
* the version code which is installed.
|
||||
* @return The keys are the package names, and their corresponding values are
|
||||
* the {@link PackageInfo#lastUpdateTime last update time} in milliseconds.
|
||||
*/
|
||||
public static Map<String, Integer> all(Context context) {
|
||||
public static Map<String, Long> all(Context context) {
|
||||
|
||||
Map<String, Integer> cachedInfo = new HashMap<>();
|
||||
Map<String, Long> cachedInfo = new HashMap<>();
|
||||
|
||||
final Uri uri = InstalledAppProvider.getContentUri();
|
||||
final String[] projection = InstalledAppProvider.DataColumns.ALL;
|
||||
@ -43,7 +43,7 @@ public class InstalledAppProvider extends FDroidProvider {
|
||||
while (!cursor.isAfterLast()) {
|
||||
cachedInfo.put(
|
||||
cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.PACKAGE_NAME)),
|
||||
cursor.getInt(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_CODE))
|
||||
cursor.getLong(cursor.getColumnIndex(DataColumns.LAST_UPDATE_TIME))
|
||||
);
|
||||
cursor.moveToNext();
|
||||
}
|
||||
@ -223,6 +223,11 @@ public class InstalledAppProvider extends FDroidProvider {
|
||||
return getAppUri(values.getAsString(DataColumns.PACKAGE_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update is not supported for {@code InstalledAppProvider}. Instead, use
|
||||
* {@link #insert(Uri, ContentValues)}, and it will overwrite the relevant
|
||||
* row, if one exists. This just throws {@link UnsupportedOperationException}
|
||||
*/
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
|
||||
throw new UnsupportedOperationException("\"Update' not supported for installed appp provider. Instead, you should insert, and it will overwrite the relevant rows if one exists.");
|
||||
|
@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* versus what Android says is installed, or processing {@link Intent}s that come
|
||||
* from {@link android.content.BroadcastReceiver}s for {@link Intent#ACTION_PACKAGE_ADDED}
|
||||
* and {@link Intent#ACTION_PACKAGE_REMOVED}
|
||||
* <p>
|
||||
* <p/>
|
||||
* Since {@link android.content.ContentProvider#insert(Uri, ContentValues)} does not check
|
||||
* for duplicate records, it is entirely the job of this service to ensure that it is not
|
||||
* inserting duplicate versions of the same installed APK. On that note,
|
||||
@ -94,7 +94,7 @@ public class InstalledAppProviderService extends IntentService {
|
||||
* is in sync with what the {@link PackageManager} tells us is installed. Once
|
||||
* completed, the relevant {@link android.content.ContentProvider}s will be
|
||||
* notified of any changes to installed statuses.
|
||||
* <p>
|
||||
* <p/>
|
||||
* The installed app cache could get out of sync, e.g. if F-Droid crashed/ or
|
||||
* ran out of battery half way through responding to {@link Intent#ACTION_PACKAGE_ADDED}.
|
||||
* This method returns immediately, and will continue to work in an
|
||||
@ -103,15 +103,18 @@ public class InstalledAppProviderService extends IntentService {
|
||||
* {@link Process#THREAD_PRIORITY_LOWEST}.
|
||||
*/
|
||||
public static void compareToPackageManager(Context context) {
|
||||
Map<String, Integer> cachedInfo = InstalledAppProvider.Helper.all(context);
|
||||
Map<String, Long> cachedInfo = InstalledAppProvider.Helper.all(context);
|
||||
|
||||
List<PackageInfo> packageInfoList = context.getPackageManager()
|
||||
.getInstalledPackages(PackageManager.GET_SIGNATURES);
|
||||
// TODO check packageInfo.lastUpdateTime for freshness
|
||||
for (PackageInfo packageInfo : packageInfoList) {
|
||||
insert(context, packageInfo);
|
||||
if (cachedInfo.containsKey(packageInfo.packageName)) {
|
||||
if (packageInfo.lastUpdateTime > cachedInfo.get(packageInfo.packageName)) {
|
||||
insert(context, packageInfo);
|
||||
}
|
||||
cachedInfo.remove(packageInfo.packageName);
|
||||
} else {
|
||||
insert(context, packageInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user