Android CursorLoader和LoaderManager错误

Arn*_* C. 1 sqlite android illegalargumentexception android-loadermanager android-cursorloader

我试图在最小API为10的情况下实现CursorLoader和LoaderManager.

但是,我继续在AsyncTaskLoader.class的第63行获得IllegalArgument异常(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();
    }
}
Run Code Online (Sandbox Code Playgroud)

下面是错误的堆栈:

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]  
Run Code Online (Sandbox Code Playgroud)

我测试了我的内容提供程序,并验证了查询方法从我的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有人在这里看到我做错了什么?

谢谢.


该应用程序似乎成功

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

然后它会抛出异常.

下面是logcat:

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) 
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 10

initLoader打电话后尝试移动lv.setAdapter.这将确保onLoadFinished(因此adapter.swapCursor(data))将被调用SimpleCursorAdapter已经与相关ListView.

此外,请确保您的数据库有一个以_id主键命名的列,CursorAdapter否则将无效._id 需要作为结果的一部分返回CursorLoader.否则将抛出异常.

  • 如果你的数据库没有名为`_id`的列,那么`CursorAdapter`不起作用,所以这就是它不起作用的原因.你的logcat中的某个地方可能有一行显示`java.lang.IllegalArgumentException:column'_id'不存在... ...下次发布你logcat的所有相关部分而不是你认为*的部分*是重要的.:) (3认同)