Unify the usage of cursors

Safer and less error-prone because:

* Always checks for null
* Checks for sizes
* Inits App/Apk lists at known capacity
* Properly closes all cursors

There are still one or two cursors that are not closed correctly and show
things like these:

W/CursorWrapperInner(19973): Cursor finalized without prior close()
This commit is contained in:
Daniel Martí 2014-03-22 00:11:56 +01:00
parent fc4a96acd8
commit 4f065492ef
5 changed files with 102 additions and 69 deletions

View File

@ -539,12 +539,15 @@ public class UpdateService extends IntentService implements ProgressListener {
int knownIdCount = cursor != null ? cursor.getCount() : 0;
List<String> knownIds = new ArrayList<String>(knownIdCount);
if (knownIdCount > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
knownIds.add(cursor.getString(0));
cursor.moveToNext();
if (cursor != null) {
if (knownIdCount > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
knownIds.add(cursor.getString(0));
cursor.moveToNext();
}
}
cursor.close();
}
return knownIds;

View File

@ -32,12 +32,15 @@ public class ApkProvider extends FDroidProvider {
}
public static List<Apk> cursorToList(Cursor cursor) {
List<Apk> apks = new ArrayList<Apk>();
int knownApkCount = cursor != null ? cursor.getCount() : 0;
List<Apk> apks = new ArrayList<Apk>(knownApkCount);
if (cursor != null) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
apks.add(new Apk(cursor));
cursor.moveToNext();
if (knownApkCount > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
apks.add(new Apk(cursor));
cursor.moveToNext();
}
}
cursor.close();
}
@ -64,12 +67,15 @@ public class ApkProvider extends FDroidProvider {
ContentResolver resolver = context.getContentResolver();
Uri uri = getContentUri(id, versionCode);
Cursor cursor = resolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
return new Apk(cursor);
} else {
return null;
Apk apk = null;
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
apk = new Apk(cursor);
}
cursor.close();
}
return apk;
}
public static List<Apk> findByApp(Context context, String appId) {

View File

@ -40,12 +40,15 @@ public class AppProvider extends FDroidProvider {
}
private static List<App> cursorToList(Cursor cursor) {
List<App> apps = new ArrayList<App>();
int knownAppCount = cursor != null ? cursor.getCount() : 0;
List<App> apps = new ArrayList<App>(knownAppCount);
if (cursor != null) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
apps.add(new App(cursor));
cursor.moveToNext();
if (knownAppCount > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
apps.add(new App(cursor));
cursor.moveToNext();
}
}
cursor.close();
}
@ -71,16 +74,19 @@ public class AppProvider extends FDroidProvider {
Cursor cursor = resolver.query(uri, projection, null, null, null );
Set<String> categorySet = new HashSet<String>();
if (cursor != null) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String categoriesString = cursor.getString(0);
if (categoriesString != null) {
for( String s : Utils.CommaSeparatedList.make(categoriesString)) {
categorySet.add(s);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String categoriesString = cursor.getString(0);
if (categoriesString != null) {
for (String s : Utils.CommaSeparatedList.make(categoriesString)) {
categorySet.add(s);
}
}
cursor.moveToNext();
}
cursor.moveToNext();
}
cursor.close();
}
List<String> categories = new ArrayList<String>(categorySet);
Collections.sort(categories);
@ -103,12 +109,15 @@ public class AppProvider extends FDroidProvider {
String[] projection) {
Uri uri = getContentUri(appId);
Cursor cursor = resolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
return new App(cursor);
} else {
return null;
App app = null;
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
app = new App(cursor);
}
cursor.close();
}
return app;
}
public static void deleteAppsWithNoApks(ContentResolver resolver) {

View File

@ -102,19 +102,22 @@ public class DBHelper extends SQLiteOpenHelper {
String[] columns = { "address", "_id" };
Cursor cursor = db.query(TABLE_REPO, columns,
"name IS NULL OR name = ''", null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String address = cursor.getString(0);
long id = cursor.getInt(1);
ContentValues values = new ContentValues(1);
String name = Repo.addressToName(address);
values.put("name", name);
String[] args = { Long.toString( id ) };
Log.i("FDroid", "Setting repo name to '" + name + "' for repo " + address);
db.update(TABLE_REPO, values, "_id = ?", args);
cursor.moveToNext();
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String address = cursor.getString(0);
long id = cursor.getInt(1);
ContentValues values = new ContentValues(1);
String name = Repo.addressToName(address);
values.put("name", name);
String[] args = { Long.toString( id ) };
Log.i("FDroid", "Setting repo name to '" + name + "' for repo " + address);
db.update(TABLE_REPO, values, "_id = ?", args);
cursor.moveToNext();
}
}
cursor.close();
}
}
}
@ -254,19 +257,23 @@ public class DBHelper extends SQLiteOpenHelper {
private void migrateRepoTable(SQLiteDatabase db, int oldVersion) {
if (oldVersion < 20) {
List<Repo> oldrepos = new ArrayList<Repo>();
Cursor c = db.query(TABLE_REPO,
Cursor cursor = db.query(TABLE_REPO,
new String[] { "address", "inuse", "pubkey" },
null, null, null, null, null);
c.moveToFirst();
while (!c.isAfterLast()) {
Repo repo = new Repo();
repo.address = c.getString(0);
repo.inuse = (c.getInt(1) == 1);
repo.pubkey = c.getString(2);
oldrepos.add(repo);
c.moveToNext();
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Repo repo = new Repo();
repo.address = cursor.getString(0);
repo.inuse = (cursor.getInt(1) == 1);
repo.pubkey = cursor.getString(2);
oldrepos.add(repo);
cursor.moveToNext();
}
}
cursor.close();
}
c.close();
db.execSQL("drop table " + TABLE_REPO);
db.execSQL(CREATE_TABLE_REPO);
for (Repo repo : oldrepos) {
@ -316,18 +323,22 @@ public class DBHelper extends SQLiteOpenHelper {
if (!columnExists(db, TABLE_REPO, "fingerprint"))
db.execSQL("alter table " + TABLE_REPO + " add column fingerprint text");
List<Repo> oldrepos = new ArrayList<Repo>();
Cursor c = db.query(TABLE_REPO,
Cursor cursor = db.query(TABLE_REPO,
new String[] { "address", "pubkey" },
null, null, null, null, null);
c.moveToFirst();
while (!c.isAfterLast()) {
Repo repo = new Repo();
repo.address = c.getString(0);
repo.pubkey = c.getString(1);
oldrepos.add(repo);
c.moveToNext();
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Repo repo = new Repo();
repo.address = cursor.getString(0);
repo.pubkey = cursor.getString(1);
oldrepos.add(repo);
cursor.moveToNext();
}
}
cursor.close();
}
c.close();
for (Repo repo : oldrepos) {
ContentValues values = new ContentValues();
values.put("fingerprint", Utils.calcFingerprint(repo.pubkey));

View File

@ -33,6 +33,7 @@ public class RepoProvider extends FDroidProvider {
if (cursor != null) {
cursor.moveToFirst();
repo = new Repo(cursor);
cursor.close();
}
return repo;
}
@ -176,13 +177,16 @@ public class RepoProvider extends FDroidProvider {
ContentResolver resolver = context.getContentResolver();
String[] projection = { ApkProvider.DataColumns._COUNT_DISTINCT_ID };
Uri apkUri = ApkProvider.getRepoUri(repoId);
Cursor result = resolver.query(apkUri, projection, null, null, null);
if (result != null && result.getCount() > 0) {
result.moveToFirst();
return result.getInt(0);
} else {
return 0;
Cursor cursor = resolver.query(apkUri, projection, null, null, null);
int count = 0;
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
count = cursor.getInt(0);
}
cursor.close();
}
return count;
}
}