2

My fragment implements the LoaderManager.LoaderCallBacks<Cursor> interface to load a list view from a content provider using a custom cursor adaptor. I use a SearchView widget to filter the data in the list view by restarting the loader as suggested by the doc http://developer.android.com/guide/components/loaders.html#restarting.

I have two questions with this approach :

  1. When I use restartLoader(), only the onCreateLoader() and then onLoadFinished() are called. I do not see a call to onLoaderReset() in the logcat. That means myadaptor.swapCursor(null) is never done during the search. So does the old cursor get leaked? Do i need to do myadaptor.swapCursor(null) before every call to restartLoader() ?

  2. Is there a more efficient approach to filter data? Because it seems way too expensive to restart the entire loader for every character entered by the user. The Android source of restartLoader() at http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/app/LoaderManager.java#648 does a lot of work of tearing down the loader resources and recreating it. It would have been more efficient if i could just do a simple requery of the data.

Code :

searchView.setOnQueryTextListener(new OnQueryTextListener() {
    @Override
    public boolean onQueryTextChange(String query) {
        Bundle queryBundle = new Bundle();
        queryBundle.putString("SearchQuery", query);
        getLoaderManager().restartLoader(0, queryBundle, myFragment.this);
        return true;
    }
}


@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle queryBundle) {
    String selection = null;
    String[] selectionArgs = null;
    if(queryBundle != null){
        selection = myTable.COLUMN_ABC + " like ?";
        selectionArgs = new String[] {"%" + queryBundle.getString("SearchQuery") + "%"};
    }
    CursorLoader cursorLoader = new CursorLoader(getActivity(), uri, projection, selection, selectionArgs, null);
        return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    myadaptor.swapCursor(data);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    myadaptor.swapCursor(null);
}
faizal
  • 3,497
  • 7
  • 37
  • 62
  • when you call restrartLoder is onLoadFinisched called? – pskink Jun 21 '14 at 19:29
  • also did you try to use FilterQueryProvider? – pskink Jun 21 '14 at 19:32
  • @pskink yes, as mentioned in #1, `onLoadFinished` is called. `FilterQueryProvider` looks interesting. The examples i found does not involve loaders, example http://stackoverflow.com/a/5057824/2105986. Do you have a sample code? – faizal Jun 22 '14 at 07:13
  • if onLoadFinished() is called so whats the problem? if using FQP just return a Cursor you get from ContentResolver. query – pskink Jun 22 '14 at 07:21
  • sample code, see my answer here http://stackoverflow.com/questions/19858843/how-to-dynamically-add-suggestions-to-autocompletetextview-with-preserving-chara – pskink Jun 22 '14 at 07:24
  • @pskink i am just looking for a more efficient way than using `restartLoader()` to filter data on every character change. I am not sure how beneficial using FQP with a loader is. Since the loader manages the cursor, the loader will anyway have to be restarted. So i don't see any advantage of using FQP. Thanks for the link but that does not involve loaders either. – faizal Jun 22 '14 at 07:35
  • with FQP you dont use loaders, just return a Cursor in runQuery, you have your own ContentProvider so call ContentResolver.query method – pskink Jun 22 '14 at 07:59

0 Answers0