CursorLoader для нескольких ContentProviders

Мне нужно создать ListAdapter, который представляет данные из нескольких ContentProviders. Сами ContentProviders представляют по одной таблице из реляционной базы данных.

Я хочу использовать систему CursorLoader для извлечения совокупных данных в ListView. Можно ли это сделать с помощью 1 загрузчика или мне нужно использовать несколько загрузчиков? Я бы предпочел использовать один.

Я не знаю, как заставить 2 ContentProvider взаимодействовать друг с другом, кроме как выполнять соединение вручную в коде, что тоже не кажется хорошим вариантом.


person Jeremy Edwards    schedule 08.12.2011    source источник


Ответы (3)


Вам нужно будет написать класс Custom Loader. Например:

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; 
    }
}

В вызывающей активности или методе фрагментов onCreate() вам нужно будет вызвать пользовательский класс загрузчика:

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) {   
    }
}
person rOrlig    schedule 11.04.2012
comment
Извините, но несколько ContentProviders — это не то же самое, что несколько таблиц в базе данных моего приложения. ContentProviders могут быть из разных приложений, и в этом случае ваше решение не является решением. (Некропостинг, но может кто подскажет) - person Giszmo; 23.09.2016

Вы можете взглянуть на CursorJoiner.

person Gábor    schedule 13.11.2014

Я сам новичок в ContentLoaders, но я еще не видел способа, которым вы могли бы использовать один ContentLoader для обработки нескольких ContentProvider.

Таблицы, которые вы запрашиваете, находятся в отдельных базах данных? Из вашего вопроса не ясно. Если все таблицы находятся в одной базе данных, одной из альтернатив может быть использование одного ContentProvider для отдельных таблиц. Данные можно объединять и возвращать к одному курсору, что означает, что вы можете использовать один CursorLoader. Метод SQLiteQueryBuilder.setTables() содержит некоторую информацию об этом:

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

и вы можете увидеть это в действии здесь:

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

это также может быть полезно: https://stackoverflow.com/a/3196484/399105

person bmaupin    schedule 12.01.2012