Question

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.

Was it helpful?

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) {   
    }
}

OTHER TIPS

You might want to take a look at CursorJoiner.

I'm new to ContentLoaders myself, but I haven't yet seen a way that you could use one ContentLoader to handle multiple ContentProviders.

Are the tables you're querying in separate databases? It isn't clear from your question. If the tables are all in the same database, one alternative might be to instead use one ContentProvider for the separate tables. The data can be joined and returned to one cursor, which means you could use one CursorLoader. The SQLiteQueryBuilder.setTables() method has some information on this:

http://developer.android.com/reference/android/database/sqlite/SQLiteQueryBuilder.html#setTables%28java.lang.String%29

and you can see it in action here:

http://code.google.com/p/openintents/source/browse/trunk/shoppinglist/ShoppingList/src/org/openintents/shopping/provider/ShoppingProvider.java

this might also be helpful: https://stackoverflow.com/a/3196484/399105

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top