Merge "Properly manage lifecycle of suggestion cursor" into jb-dev
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index f8fc4cd..1c526a5 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -16,6 +16,7 @@
package com.android.contacts.list;
import com.android.contacts.R;
+import com.android.contacts.list.JoinContactLoader.JoinContactLoaderResult;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
@@ -78,13 +79,14 @@
break;
}
case JoinContactListAdapter.PARTITION_ALL_CONTACTS: {
- Cursor suggestionsCursor = ((JoinContactLoader) loader).getSuggestionsCursor();
+ Cursor suggestionsCursor = ((JoinContactLoaderResult) data).suggestionCursor;
onContactListLoaded(suggestionsCursor, data);
break;
}
}
}
+ @Override
public void onLoaderReset(Loader<Cursor> loader) {
}
};
diff --git a/src/com/android/contacts/list/JoinContactLoader.java b/src/com/android/contacts/list/JoinContactLoader.java
index c43560e..beb5208 100644
--- a/src/com/android/contacts/list/JoinContactLoader.java
+++ b/src/com/android/contacts/list/JoinContactLoader.java
@@ -18,19 +18,46 @@
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
-import android.database.MatrixCursor;
+import android.database.CursorWrapper;
import android.net.Uri;
-import android.util.Log;
/**
* A specialized loader for the Join Contacts UI. It executes two queries:
* join suggestions and (optionally) the full contact list.
+ *
+ * This loader also loads the "suggestion" cursor, which can be accessed with:
+ * {@code ((JoinContactLoaderResult) result).suggestionCursor }
*/
public class JoinContactLoader extends CursorLoader {
private String[] mProjection;
private Uri mSuggestionUri;
- private Cursor mSuggestionsCursor;
+
+ /**
+ * Actual returned class. It's guaranteed that this loader always returns an instance of this
+ * class. This class is needed to tie the lifecycle of the second cursor to that of the
+ * primary one.
+ *
+ * Note we can't change the result type of this loader itself, because CursorLoader
+ * extends AsyncTaskLoader<Cursor>, not AsyncTaskLoader<? extends Cursor>
+ */
+ public static class JoinContactLoaderResult extends CursorWrapper {
+ public final Cursor suggestionCursor;
+
+ public JoinContactLoaderResult(Cursor baseCursor, Cursor suggestionCursor) {
+ super(baseCursor);
+ this.suggestionCursor = suggestionCursor;
+ }
+
+ @Override
+ public void close() {
+ try {
+ suggestionCursor.close();
+ } finally {
+ super.close();
+ }
+ }
+ }
public JoinContactLoader(Context context) {
super(context, null, null, null, null, null);
@@ -46,16 +73,12 @@
this.mProjection = projection;
}
- public Cursor getSuggestionsCursor() {
- return mSuggestionsCursor;
- }
-
@Override
public Cursor loadInBackground() {
// First execute the suggestions query, then call super.loadInBackground
// to load the entire list
- mSuggestionsCursor = getContext().getContentResolver()
+ final Cursor suggestionsCursor = getContext().getContentResolver()
.query(mSuggestionUri, mProjection, null, null, null);
- return super.loadInBackground();
+ return new JoinContactLoaderResult(super.loadInBackground(), suggestionsCursor);
}
}
\ No newline at end of file