CursorLoader не показывает базы данных - PullRequest
2 голосов
/ 13 февраля 2012

У меня есть CursorLoader в ListFragment (то есть внутри ViewPager), который запрашивает базу данных.У меня есть поставщик контента для этой базы данных, который, как я проверял, работает.

Проблема заключается в следующем: когда приложение запускается впервые, отдельная служба вызывает массив вставка в ContentProvider:

public int bulkInsert(Uri uri, ContentValues[] values) {
    if(LOGV) Log.v(TAG, "insert(uri=" + uri + ", values" + values.toString() + ")");

    final SQLiteDatabase db = openHelper.getWritableDatabase();
    final int match = uriMatcher.match(uri);

    switch(match) {
        case SNAP: {
            db.beginTransaction();
            for(ContentValues cv : values) {
                db.insertOrThrow(Tables.SNAP, null, cv);                        
            }
            db.setTransactionSuccessful();
            db.endTransaction();

            getContext().getApplicationContext().getContentResolver().notifyChange(uri, null);
            return values.length;
        }

1012 * во фрагменте списка возвращает 0 строк, хотя при самом первом запуске (когда создается база данных).Если я закрою и перезапущу приложение, CursorLoader прекрасно работает и вернет именно то, что мне нужно.Я пытался реализовать ожидание через обработчик, но, похоже, это не помогло.Вот ListFragment, который использует CursorLoader:

public class DataBySnapFragment extends ListFragment implements LoaderCallbacks<Cursor> {   
    public static final String TAG = "DataBySnapFragment";

    protected Cursor cursor = null;
    private DataBySnapAdapter adapter;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d(TAG, "RELOADING!!!!!");
            onLoadDelay();
        }
    };  

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated");

        adapter = new DataBySnapAdapter(getActivity(), 
                                        R.layout.list_item_databysnap, 
                                        null, 
                                        new String[]{}, 
                                        new int[]{}, 
                                        0);
        setListAdapter(adapter);        
        getLoaderManager().initLoader(0, null, this);       
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_databysnap, null);
        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("error_workaround_1",
                           "workaroundforerror:Issue 19917,
                           http://code.google.com/p/android/issues/detail?id=19917");
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        CursorLoader cursorLoader = new CursorLoader(getActivity(),
                                                     Snap.CONTENT_URI,
                                                     null,
                                                     null,
                                                     null,
                                                     Snap.DATA_MONTH_TO_DATE + " DESC LIMIT 6");

        return cursorLoader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Log.d(TAG, "data rows: " + data.getCount());
        if(data.getCount() <= 0) {
            delayThread();
        } else {
            adapter.swapCursor(data);           
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        adapter.swapCursor(null);
    }

    private void onLoadDelay() {
        getLoaderManager().initLoader(0, null, this);       
    }

    private void delayThread() {
        new Thread() {
            public void run() {
                longTimeMethod();
                handler.sendEmptyMessage(0);
            }
        }.start();
    }

    private void longTimeMethod() {
        try {
            Thread.sleep(12000);
        } catch (InterruptedException e) {
            Log.e("tag", e.getMessage());
        }
    }   
}

Может кто-нибудь сообщить мне, почему это может происходить, или, по крайней мере, направить меня в правильном направлении?Спасибо!

Ответы [ 3 ]

0 голосов
/ 11 апреля 2012

Когда бы ваша массовая вставка не была сделана, вы должны отправить сообщение обратно фрагменту / деятельности, реализующему интерфейс LoaderManager.LoaderCallbacks.Когда действие / фрагмент получает сообщение, вам необходимо вызвать getLoaderManager (). RestartLoader (0, null, this) для запроса БД.

Это то же, что и в примере приложения http://developer.android.com/guide/topics/fundamentals/loaders.html

0 голосов
/ 30 июля 2013

Попробуйте изменить onLoadFinished таким образом:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    Log.d(TAG, "data rows: " + data.getCount());
    if(data.getCount() <= 0) {
        delayThread();
    } else {
        // set the notification for the cursor
        data.setNotificationUri(getActivity().getContentResolver(), Snap.CONTENT_URI);
        adapter.swapCursor(data);           
    }
}
0 голосов
/ 13 февраля 2012

Если вы не остановили основной поток, создание нового потока и его перевод в спящий режим ничего не решали бы.

Я не могу точно сказать, что именно может быть не так, но похоже, что вам может понадобиться обновить ваши данные. Для тестирования вы можете попытаться создать кнопку с OnClickListener, которая обновляет содержимое данных и повторно извлекает его из базы данных.

...