After downloading index, remove apks no longer in the index.
It adds an extra 600ms on my Nexus 4 with ~2000 apks from the F-Droid index. But I think it is the only way, as we really need to iterate over every single installed apk, to see if it is still wanted. The up side is that we can query for a large amount of them, rather than quering individually for each apk. NOTE: I haven't added a new status message yet, because we are about to do a stable release. After the stable release, I'll add a new status message to cover for this > half a second (on my relatively fast device). This will probably be part of an overhaul of the update process in general, including a proper progress dialog.
This commit is contained in:
parent
05d8e409c4
commit
468b6717ee
@ -313,11 +313,14 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
calcIconUrls(this, apksToUpdate, appsToUpdate, repos);
|
calcIconUrls(this, apksToUpdate, appsToUpdate, repos);
|
||||||
calcCurrentApk(apksToUpdate, appsToUpdate);
|
calcCurrentApk(apksToUpdate, appsToUpdate);
|
||||||
|
|
||||||
|
// Need to do this BEFORE updating the apks, otherwise when it continually
|
||||||
|
// calls "get apks for repo X" then it will be getting the newly created apks
|
||||||
|
removeApksNoLongerInRepo(apksToUpdate, updatedRepos);
|
||||||
|
|
||||||
int totalInsertsUpdates = listOfAppsToUpdate.size() + apksToUpdate.size();
|
int totalInsertsUpdates = listOfAppsToUpdate.size() + apksToUpdate.size();
|
||||||
updateOrInsertApps(listOfAppsToUpdate, totalInsertsUpdates, 0);
|
updateOrInsertApps(listOfAppsToUpdate, totalInsertsUpdates, 0);
|
||||||
updateOrInsertApks(apksToUpdate, totalInsertsUpdates, listOfAppsToUpdate.size());
|
updateOrInsertApks(apksToUpdate, totalInsertsUpdates, listOfAppsToUpdate.size());
|
||||||
removeApksFromRepos(disabledRepos);
|
removeApksFromRepos(disabledRepos);
|
||||||
removeApksNoLongerInRepo(listOfAppsToUpdate, updatedRepos);
|
|
||||||
removeAppsWithoutApks();
|
removeAppsWithoutApks();
|
||||||
notifyContentProviders();
|
notifyContentProviders();
|
||||||
|
|
||||||
@ -618,7 +621,7 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return list of apps from "fromApks" which are already in the database.
|
* Return list of apps from the "apks" argument which are already in the database.
|
||||||
*/
|
*/
|
||||||
private List<Apk> getKnownApks(List<Apk> apks) {
|
private List<Apk> getKnownApks(List<Apk> apks) {
|
||||||
List<Apk> knownApks = new ArrayList<Apk>();
|
List<Apk> knownApks = new ArrayList<Apk>();
|
||||||
@ -701,26 +704,54 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
* belong to the repo which are not in the current list of apks that were
|
* belong to the repo which are not in the current list of apks that were
|
||||||
* retrieved.
|
* retrieved.
|
||||||
*/
|
*/
|
||||||
private void removeApksNoLongerInRepo(List<App> appsToUpdate,
|
private void removeApksNoLongerInRepo(List<Apk> apksToUpdate, List<Repo> updatedRepos) {
|
||||||
List<Repo> updatedRepos) {
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
List<Apk> toRemove = new ArrayList<Apk>();
|
||||||
|
|
||||||
|
String[] fields = {
|
||||||
|
ApkProvider.DataColumns.APK_ID,
|
||||||
|
ApkProvider.DataColumns.VERSION_CODE,
|
||||||
|
ApkProvider.DataColumns.VERSION,
|
||||||
|
};
|
||||||
|
|
||||||
for (Repo repo : updatedRepos) {
|
for (Repo repo : updatedRepos) {
|
||||||
Log.d("FDroid", "Removing apks no longer in repo " + repo.address);
|
List<Apk> existingApks = ApkProvider.Helper.findByRepo(this, repo, fields);
|
||||||
// TODO: Implement
|
for (Apk existingApk : existingApks) {
|
||||||
|
if (!isApkToBeUpdated(existingApk, apksToUpdate)) {
|
||||||
|
toRemove.add(existingApk);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long duration = System.currentTimeMillis() - startTime;
|
||||||
|
Log.d("FDroid", "Found " + toRemove.size() + " apks no longer in the updated repos (took " + duration + "ms)");
|
||||||
|
|
||||||
|
if (toRemove.size() > 0) {
|
||||||
|
ApkProvider.Helper.deleteApks(this, toRemove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isApkToBeUpdated(Apk existingApk, List<Apk> apksToUpdate) {
|
||||||
|
for (Apk apkToUpdate : apksToUpdate) {
|
||||||
|
if (apkToUpdate.vercode == existingApk.vercode && apkToUpdate.id.equals(existingApk.id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeApksFromRepos(List<Repo> repos) {
|
private void removeApksFromRepos(List<Repo> repos) {
|
||||||
for (Repo repo : repos) {
|
for (Repo repo : repos) {
|
||||||
Log.d("FDroid", "Removing apks from repo " + repo.address);
|
|
||||||
Uri uri = ApkProvider.getRepoUri(repo.getId());
|
Uri uri = ApkProvider.getRepoUri(repo.getId());
|
||||||
getContentResolver().delete(uri, null, null);
|
int numDeleted = getContentResolver().delete(uri, null, null);
|
||||||
|
Log.d("FDroid", "Removing " + numDeleted + " apks from repo " + repo.address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAppsWithoutApks() {
|
private void removeAppsWithoutApks() {
|
||||||
Log.d("FDroid", "Removing aps that don't have any apks");
|
int numDeleted = getContentResolver().delete(AppProvider.getNoApksUri(), null, null);
|
||||||
getContentResolver().delete(AppProvider.getNoApksUri(), null, null);
|
Log.d("FDroid", "Removing " + numDeleted + " apks that don't have any apks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import android.database.Cursor;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.BaseColumns;
|
import android.provider.BaseColumns;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import org.fdroid.fdroid.UpdateService;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -59,6 +60,12 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
resolver.delete(uri, null, null);
|
resolver.delete(uri, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deleteApks(Context context, List<Apk> apks) {
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
Uri uri = getContentUri(apks);
|
||||||
|
resolver.delete(uri, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static Apk find(Context context, String id, int versionCode) {
|
public static Apk find(Context context, String id, int versionCode) {
|
||||||
return find(context, id, versionCode, DataColumns.ALL);
|
return find(context, id, versionCode, DataColumns.ALL);
|
||||||
}
|
}
|
||||||
@ -102,6 +109,13 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
Cursor cursor = resolver.query(uri, fields, null, null, null);
|
Cursor cursor = resolver.query(uri, fields, null, null, null);
|
||||||
return cursorToList(cursor);
|
return cursorToList(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Apk> findByRepo(Context context, Repo repo, String[] fields) {
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
Uri uri = getRepoUri(repo.getId());
|
||||||
|
Cursor cursor = resolver.query(uri, fields, null, null, null);
|
||||||
|
return cursorToList(cursor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface DataColumns extends BaseColumns {
|
public interface DataColumns extends BaseColumns {
|
||||||
@ -392,20 +406,15 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
query = query.add(queryApp(uri.getLastPathSegment()));
|
query = query.add(queryApp(uri.getLastPathSegment()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODE_LIST:
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
"Can't delete all apks. " +
|
|
||||||
"Can only delete those belonging to an app, or a repo.");
|
|
||||||
|
|
||||||
case CODE_APKS:
|
case CODE_APKS:
|
||||||
throw new UnsupportedOperationException(
|
query = query.add(queryApks(uri.getLastPathSegment()));
|
||||||
"Can't delete arbitrary apks. " +
|
break;
|
||||||
"Can only delete those belonging to an app, or a repo.");
|
|
||||||
|
case CODE_LIST:
|
||||||
|
throw new UnsupportedOperationException("Can't delete all apks.");
|
||||||
|
|
||||||
case CODE_SINGLE:
|
case CODE_SINGLE:
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException("Can't delete individual apks.");
|
||||||
"Can't delete individual apks. " +
|
|
||||||
"Can only delete those belonging to an app, or a repo.");
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.e("FDroid", "Invalid URI for apk content provider: " + uri);
|
Log.e("FDroid", "Invalid URI for apk content provider: " + uri);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user