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

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

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

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

Ответ 1

Вам нужно будет написать класс 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) {   
    }
}

Ответ 2

Возможно, вам стоит взглянуть на CursorJoiner.

Ответ 3

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

Являются ли таблицы, которые вы запрашиваете в разных базах данных? Это не ясно из вашего вопроса. Если все таблицы находятся в одной базе данных, одним из вариантов может быть использование одного 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

это также может быть полезно: fooobar.com/info/465408/...