Search code examples
androiddatabaseandroid-contentproviderlistadapterandroid-cursorloader

CursorLoader for Multiple ContentProviders


I need to make a ListAdapter that presents data from multiple ContentProviders. The ContentProviders themselves represent one table each from relational database.

I want to use the CursorLoader system to retrieve aggregate data into ListView. Is this possible to do with 1 loader or do I need to use multiple loaders? I'd prefer to use one.

I'm not sure how I can have 2 ContentProviders interact with each other beyond doing the join manually in code which doesn't seem like a great option either.


Solution

  • You will have to write a Custom Loader class. For example:

    public class FooLoader extends AsyncTaskLoader {
    
        Context context;
    
        public FooLoader(Context context) {
            super(context);
            this.context = context;
        }
    
        @Override
        public Cursor loadInBackground() {
            Log.d(TAG, "loadInBackground");
            YourDatabase dbHelper = new YourDataBase(context);
            SQLiteDatabase db= dbHelper.getReadableDatabase();
    
            /*** create a custom cursor whether it is join of multiple tables or complex query**/
            Cursor cursor = db.query(<TableName>, null,null, null, null, null, null, null);
            return cursor; 
        }
    }
    

    In the calling activity or fragments onCreate() method, you would need to call the custom loader class:

    public class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, "onCreate():" + mContent);
            Loader loader = getLoaderManager().initLoader(0, null, this);
            loader.forceLoad();
        }   
    
        @Override
        public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
            Log.d(TAG, "onCreateLoader()")  ;
            return new FooLoader(getActivity());
        }
    
        @Override
        public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
            Log.d(TAG, "onLoadFinished");            
        }
    
        @Override
        public void onLoaderReset(Loader<Cursor> cursorLoader) {   
        }
    }