Ошибка Android CursorLoader и LoaderManager

Я пытаюсь реализовать CursorLoader и LoaderManager с минимальным API 10.

Тем не менее, я продолжаю получать исключение IllegalArgument Exception в строке 63 AsyncTaskLoader.class (исходный код AsyncTaskLoader.class, где происходит исключение, приведен ниже, и в этом ссылка.

/* Runs on the UI thread */
@Override
protected void onPostExecute(D data) {
    if (DEBUG) Log.v(TAG, this + " onPostExecute");
    try {
        AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
    } finally {
        done.countDown();
    }
}

Ниже приведен стек при ошибке:

AsyncTaskLoader$LoadTask.onPostExecute(Object) line: 63 
AsyncTaskLoader$LoadTask(ModernAsyncTask).finish(Object) line: 461  
ModernAsyncTask.access$500(ModernAsyncTask, Object) line: 47    
ModernAsyncTask$InternalHandler.handleMessage(Message) line: 474    
ModernAsyncTask$InternalHandler(Handler).dispatchMessage(Message) line: 99  
Looper.loop() line: 137 
ActivityThread.main(String[]) line: 4424    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 511  
ZygoteInit$MethodAndArgsCaller.run() line: 784  
ZygoteInit.main(String[]) line: 551 
NativeStart.main(String[]) line: not available [native method]  

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

import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListView;

public class Screen1_MainData extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    SimpleCursorAdapter adapter;
    ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.screen1_maindata);
        initLoader();
    }

    void initLoader() {
        String[] uiBindFrom = { Useful_Info_TableMetaData.USEFUL_INFO_COLUMN_NAME };
        int[] uiBindTo = { R.id.name };
        lv = (ListView) findViewById(R.id.screen1_MainListView);
        getSupportLoaderManager().initLoader(0, null, this);

        adapter = new SimpleCursorAdapter(this, R.layout.row, null, uiBindFrom,
                uiBindTo, 0);
        lv.setAdapter(adapter);    
    }

@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {

    String[] projection = { Useful_Info_TableMetaData.USEFUL_INFO_COLUMN_NAME };

    return new CursorLoader(
            this, // The Activity context
            Useful_Info_TableMetaData.CONTENT_URI, projection, null, null,
            null);
}

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        adapter.swapCursor(data);
    }

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

Кто-нибудь видит здесь что-то, что я делаю неправильно?

Спасибо.


Приложение, кажется, делает это

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    adapter.swapCursor(data);
}

а затем он бросает исключение там.

Ниже приведен логарифм:

08-03 23:33:20.736: E/AndroidRuntime(17256): FATAL EXCEPTION: main 
08-03 23:33:20.736: E/AndroidRuntime(17256): java.lang.IllegalArgumentException: column '_id' does not exist 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:267) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:78) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:344) 
08-03 23:33:20.736: E/AndroidRuntime(17256): at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326) 

person ControlAltDelete    schedule 03.08.2012    source источник
comment
Почему вы импортировали ListFragment и что вы делаете с ListFragment, если используете его?   -  person Alex Lockwood    schedule 04.08.2012
comment
извините, это было из предыдущей попытки исправить это. В настоящее время он не используется. Я обновлю свой пост. Спасибо   -  person ControlAltDelete    schedule 04.08.2012
comment
Почему у вас есть оператор try-catch в onCreateLoader?   -  person Alex Lockwood    schedule 04.08.2012
comment
Не могли бы вы опубликовать больше вывода logcat? Вывод, который вы опубликовали, на самом деле не имеет отношения к ошибке, которую вы получаете... в какой строке вашей деятельности возникает исключение?   -  person Alex Lockwood    schedule 04.08.2012
comment
Вы все еще не опубликовали полный лог-код... Я не вижу строки, в которой говорится, что IllegalStateException был выброшен. Можете ли вы опубликовать все это только для ясности?   -  person Alex Lockwood    schedule 04.08.2012
comment
Я не вижу IllegalArgumentException в опубликованном вами логарифме... Я также не вижу ничего о AsyncTaskLoader и т. д. в логарифме. Это также невероятно трудно читать ... попробуйте скопировать и вставить его, чтобы в следующий раз каждая строка была на отдельной строке ... и вы должны использовать блоки кода (а не блоки кавычек) для вывода logcat.   -  person Alex Lockwood    schedule 04.08.2012
comment
Он не отображается там, но отображается в трассировке стека, и приложение перестает работать. Я собираюсь удалить logcat, потому что там нет ничего, что могло бы помочь решить эту проблему.   -  person ControlAltDelete    schedule 04.08.2012
comment
Опубликуйте строку, в которой упоминается IllegalArgumentException... вот о чем я прошу, лол   -  person Alex Lockwood    schedule 04.08.2012


Ответы (1)


Попробуйте переместить initLoader после вашего звонка на lv.setAdapter. Это гарантирует, что onLoadFinished (и, следовательно, adapter.swapCursor(data)) будет вызываться после того, как SimpleCursorAdapter будет связано с ListView .

Кроме того, убедитесь, что в вашей базе данных есть столбец с именем _id для вашего первичного ключа, иначе CursorAdapter не будет работать. _id необходимо вернуть как часть результатов CursorLoader. В противном случае будет выброшено исключение.

person Alex Lockwood    schedule 03.08.2012
comment
Только что попробовал, но результат тот же. Я просмотрел logcat, и никаких сообщений об ошибках/предупреждениях не отображалось, только типичные подробные сообщения от отладчика. Любые другие мысли, которые я натыкался на стену в течение последних двух дней по этому поводу. Спасибо - person ControlAltDelete; 04.08.2012
comment
Когда он падает? Он просто случайно вылетает в фоновом режиме или что? Может быть, поместите несколько вызовов Log.v в свой Activity, чтобы вы могли видеть, что выполняется до того, как будет выброшен Exception? - person Alex Lockwood; 04.08.2012
comment
Хорошо, только что сделал это. Это делает его @Override public void onLoadFinished (загрузчик Loader‹Cursor›, данные курсора) { adapter.swapCursor(data); Это строка, на которой происходит сбой с исключением IllegalArgument Exception. } - person ControlAltDelete; 04.08.2012
comment
Есть ли в вашей базе данных столбец с именем _id? - person Alex Lockwood; 04.08.2012
comment
до преобразования в поставщика контента из прямого доступа к базе данных Sqlite у меня не было столбца _id. Я использовал имя в качестве своего уникального первичного ключа. - person ControlAltDelete; 04.08.2012
comment
CursorAdapter не работает, если в вашей базе данных нет столбца с именем _id, вот почему он не работает. Где-то в вашем логарифме, вероятно, есть строка, которая читает java.lang.IllegalArgumentException: column '_id' does not exist... в следующий раз опубликуйте все соответствующие части вашего логарифма, а не только те части, которые вы считаете важными. :) - person Alex Lockwood; 04.08.2012
comment
Это был весь logcat от запуска программы до сбоя. - person ControlAltDelete; 04.08.2012
comment
давайте продолжим это обсуждение в чате - person Alex Lockwood; 04.08.2012