Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14ca8620 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Properly manage lifecycle of suggestion cursor

JoinContactLoader loads two cursor in a single load, which is doable,
but not in the way the old code did.

We need to tie the second cursor to the primary cursor in order to
have the framework manage its lifecycle properly.

Bug 6216651

Change-Id: Ia25431832a5b8b94bfd1b319e3d2d4533a4d3840
parent b7b9508f
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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 @@ public class JoinContactListFragment extends ContactEntryListFragment<JoinContac
                    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) {
        }
    };
+32 −9
Original line number Diff line number Diff line
@@ -18,19 +18,46 @@ package com.android.contacts.list;
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 @@ public class JoinContactLoader extends CursorLoader {
        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