Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
913 views
in Technique[技术] by (71.8m points)

listview - Android column '_id' does not exist?

I'm having trouble with something that works in the Notepad example. Here's the code from the NotepadCodeLab/Notepadv1Solution:

String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
int[] to = new int[] { R.id.text1 };

SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);

This code seems to work fine. But just to be clear, I ran the ADB utility and run SQLite 3. I inspected the schema as follows:

sqlite> .schema

CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE notes (_id integer primary key autoincrement, title text
not null, body text not null);

All seems good to me.


Now on to my application, which, as far as I can see, is basically the same with a few minor changes. I've simplified and simplified my code, but the problem persists.

String[] from = new String[] { "x" };
int[] to = new int[] { R.id.x };

SimpleCursorAdapter adapter = null;
try
{
    adapter = new SimpleCursorAdapter(this, R.layout.circle_row, cursor, from, to);
}
catch (RuntimeException e)
{
    Log.e("Circle", e.toString(), e);
}

When I run my application, I get a RuntimeException and the following prints in LogCat from my Log.e() statement:

LogCat Message:

java.lang.IllegalArgumentException: column '_id' does not exist

So, back to SQLite 3 to see what's different about my schema:

sqlite> .schema CREATE TABLE android_metadata (locale TEXT); CREATE TABLE circles (_id integer primary key autoincrement, sequence integer, radius real, x real, y real);

I don't see how I'm missing the '_id'.

What have I done wrong?

One thing that's different between my application and the Notepad example is that I started by creating my application from scratch using the Eclipse wizard while the sample application comes already put together. Is there some sort of environmental change I need to make for a new application to use a SQLite database?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I see, the documentation for CursorAdapter states:

The Cursor must include a column named _id or this class will not work.

The SimpleCursorAdapter is a derived class, so it appears this statement applies. However, the statement is technically wrong and somewhat misleading to a newbie. The result set for the cursor must contain _id, not the cursor itself.
I'm sure this is clear to a DBA because that sort of shorthand documentation is clear to them, but for those newbies, being incomplete in the statement causes confusion. Cursors are like iterators or pointers, they contain nothing but a mechanism for transversing the data, they contain no columns themselves.

The Loaders documentation contains an example where it can be seen that the _id is included in the projection parameter.

static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
    Contacts._ID,
    Contacts.DISPLAY_NAME,
    Contacts.CONTACT_STATUS,
    Contacts.CONTACT_PRESENCE,
    Contacts.PHOTO_ID,
    Contacts.LOOKUP_KEY,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // ...
    return new CursorLoader(getActivity(), baseUri,
            CONTACTS_SUMMARY_PROJECTION, select, null,
            Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...