"列' _id'不存在"即使它确实如此

时间:2014-08-16 14:11:59

标签: android database sqlite

编辑:之前的标题来自草稿,对不起。

我知道有关于此主题的几个主题,但我没有找到适合我的解决方案。我应用了一些提示,但错误仍然存​​在。

这是我得到的错误,尽管我有一个“_id”栏:

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

我现在正在解决这个问题,我希望有人可以帮助我。我得到的第一个错误来自“super(context,c,flags)”行;在“GridViewCustomAdapter”中(标记为注释)。

DataSet(SQLiteOpenHelper):

public class DataSet extends SQLiteOpenHelper {

    // Database Version
    private static int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = "minecraft";
    // Items table name
    private static final String TABLE_ITEMS = "items";

    // Items Table Columns names
    public static final String KEY_ID = "_id";
    public static final String KEY_MC_ID = "mc_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_CATEGORY = "category";
    public static final String KEY_SUBCATEGORY = "subcategory";
    public static final String KEY_URL_EXT = "url_ext";

    private static final String[] COLUMNS = { KEY_ID, KEY_MC_ID, KEY_NAME, KEY_CATEGORY, KEY_SUBCATEGORY, KEY_URL_EXT };

    public DataSet(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }


   @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d("R", "oncreate...");
        // SQL statement to create book table
        String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + " (" +
                KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                KEY_MC_ID + " TEXT," +
                KEY_NAME + " TEXT," +
                KEY_CATEGORY + " TEXT," +
                KEY_SUBCATEGORY + " TEXT," +
                KEY_URL_EXT + " TEXT )";

        // create items table
        db.execSQL(CREATE_ITEMS_TABLE);
/*
        FileInputStream fis;
        fis = getApplicationContext().openFileInput("test.txt");
        StringBuilder fileContent = new StringBuilder();

        byte[] buffer = new byte[1024];
        try {
            int n;
            while ((n = fis.read(buffer)) != -1) {
                fileContent.append(new String(buffer, 0, n));
            }
        } catch (Exception e) {

        }
*/
        //Delete
        /*SQLiteDatabase dba = this.getWritableDatabase();
        Item item = new Item(12, "Diamond Sword", "Combat", null, "C:/Users", "C:/Users/images");

        ContentValues values = new ContentValues();
        values.put(KEY_MC_ID, item.getMcId()); // get author
        values.put(KEY_CATEGORY, item.getCategory());
        values.put(KEY_SUBCATEGORY, item.getSubcategory());
        values.put(KEY_URL_EXT, item.getUrlExtension());
        values.put(KEY_IMAGE_REF, item.getImageRef());
        dba.insert(TABLE_ITEMS, null, values);

        Cursor cursor = dba.query(TABLE_ITEMS, COLUMNS, KEY_ID, new String[] {"*"}, null, null, null, null);
        if (cursor == null) {
            Log.d("Tag: ", "Error, nichts gefunden!");
        } else {
            cursor.moveToFirst();
            String p = cursor.getString(2);
            Log.d("Tag", p);
        }*/
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older items table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
        // create fresh items table
        this.onCreate(db);
    }


    public Cursor getAllItems() {
        SQLiteDatabase database = this.getReadableDatabase();
        return database.query(TABLE_ITEMS, null, null, null, null, null, null, null);
    }


    public void addItem(Item item){
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put(KEY_MC_ID, item.getMcId()); // get author
        values.put(KEY_NAME, item.getName());
        values.put(KEY_CATEGORY, item.getCategory());
        values.put(KEY_SUBCATEGORY, item.getSubcategory());
        values.put(KEY_URL_EXT, item.getUrlExtension());

        // 3. insert
        //db.insert(TABLE_ITEMS, null, values);

        //TEST START
        db.insertWithOnConflict(TABLE_ITEMS,null,values,SQLiteDatabase.CONFLICT_REPLACE);
        //TEST FINISH

        // 4. close
        db.close();
    }

    public void addItemList(List<Item> list) {
        int oldVersion = this.getWritableDatabase().getVersion();
        onUpgrade(this.getWritableDatabase(), oldVersion, ++oldVersion);
        SQLiteDatabase db = this.getWritableDatabase();
        db.needUpgrade(12);
        Calendar c = Calendar.getInstance();
        Date start = c.getTime();
        Log.d("Started inserting...",start.toString());
        for (Item i : list) {
            ContentValues values = new ContentValues();
            values.put(KEY_MC_ID, i.getMcId()); // get author
            values.put(KEY_NAME, i.getName());
            values.put(KEY_CATEGORY, i.getCategory());
            values.put(KEY_SUBCATEGORY, i.getSubcategory());
            values.put(KEY_URL_EXT, i.getUrlExtension());
            //db.insert(TABLE_ITEMS, null, values);
            db.insertWithOnConflict(TABLE_ITEMS,null,values,SQLiteDatabase.CONFLICT_IGNORE);
        }
        Date end = c.getTime();
        Log.d("Finished inserting: ", end.toString());
        db.close();
    }

    public Item getItem(String mc_id){

        // 1. get reference to readable DB
        SQLiteDatabase db = this.getReadableDatabase();

        // 2. build query
        Cursor cursor =
                db.query(TABLE_ITEMS, // a. table
                        COLUMNS, // b. column names
                        KEY_MC_ID, // c. selections    OLD, FALLS ES FAILT: KEY_ID + " = ?",
                        new String[] { String.valueOf(mc_id) }, // d. selections args
                        null, // e. group by
                        null, // f. having
                        null, // g. order by
                        null); // h. limit

        // 3. if we got results get the first one
        if (cursor.moveToFirst()) {

            // 4. build book object
            Item item = new Item();
            item.setMcId(cursor.getString(1));
            item.setName(cursor.getString(2));
            item.setCategory(cursor.getString(3));
            item.setSubcategory(cursor.getString(4));
            item.setUrlExtension(cursor.getString(5));

            return item;
        }
        return null;    //Else...
    }

    public boolean containsItems() {
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor =
            db.query(TABLE_ITEMS, // a. table
                    null, // b. column names
                    null, // c. selections
                    null, // d. selections args
                    null, // e. group by
                    null, // f. having
                    null, // g. order by
                    null); // h. limit
        if (cursor.getCount() > 0) return true;
        else return false;
    }

    //public Cursor getSpecificItems(String key_mc_id, String key_nameE, String key_cat, String key_subcat, String key_url_ext) {
    public Cursor getSpecificItems(String[] selectionArgs) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.rawQuery("SELECT " + KEY_SUBCATEGORY + " FROM " + TABLE_ITEMS + " WHERE " + KEY_SUBCATEGORY + " = ?", selectionArgs);
        return cursor;
    }
}

DatabaseController:

public class DatabaseController {

    private Context context;
    private DataSet dataset;

    public static Resources resources = null;

    List<Item> itemList = new ArrayList<Item>();

    public DatabaseController(Context context) {
        this.context = context;
        this.dataset = new DataSet(context);
    }

    public void readDataAndAddToDatabase() {
        try {
            resources = context.getResources();
            InputStream is = resources.openRawResource(R.raw.database_values);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);

            String input;
            while ((input = reader.readLine()) != null) {
                itemList.add(new Item(input));
            }
            dataset.addItemList(itemList);
        } catch (Exception e) {
            Log.d("Fehler!!!!!!!!!!!!!!!!!!!!!!!!", "");
            e.printStackTrace();
        }
    }

    public Cursor getSpecificItems(String[] selectionArgs) {
        return this.dataset.getSpecificItems(selectionArgs);
    }

    public boolean containsItems() {
        return dataset.containsItems();
    }

    public DataSet getDatabase() {
        return this.dataset;
    }

    public Cursor getAllItems() {
        return dataset.getAllItems();
    }
}

GridViewCustonAdapter(CursorAdapter):

public class GridViewCustomAdapter extends CursorAdapter
{
    Context context;
    private LayoutInflater mInflater;

    public GridViewCustomAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);    //The Crash seems to start from here...
        this.context = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        TextView content = (TextView) view.findViewById(R.id.textView);
        content.setText(cursor.getString(cursor.getColumnIndex(DataSet.KEY_NAME)));

        ImageView image = (ImageView) view.findViewById(R.id.imageView);
        image.setImageBitmap(getBitmapFromAsset(cursor.getString(cursor.getColumnIndex(DataSet.KEY_MC_ID + ".png"))));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return mInflater.inflate(R.layout.item_layout, parent, false);
    }

    private Bitmap getBitmapFromAsset(String strName)
    {
        AssetManager assetManager = context.getAssets();
        InputStream istr = null;
        try {
            istr = assetManager.open(strName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Bitmap bitmap = BitmapFactory.decodeStream(istr);
        return bitmap;
    }
}

ItemsView(活动):

public class ItemsView extends Activity {

    DatabaseController dbc;
    GridView gridView;
    GridViewCustomAdapter gridViewCustomAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

//        String category = savedInstanceState.getString(getString(R.string.key_category));
//        String subcategory = savedInstanceState.getString(getString(R.string.key_subcategory));
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_items_view);

        this.dbc = new DatabaseController(this);


        Cursor cursor = dbc.getSpecificItems(new String[] { "tools" });

        gridView = (GridView)findViewById(R.id.gridViewCustom);
        // Create the Custom Adapter Object
        gridViewCustomAdapter = new GridViewCustomAdapter(this, cursor, 0);
        // Set the Adapter to GridView
        gridView.setAdapter(gridViewCustomAdapter);

        // Handling touch/click Event on GridView Item
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
                String selectedItem;
                if(position%2==0)
                    selectedItem="Facebook" + " @Position: " + position;
                else
                    selectedItem="Twitter" + " @Position: " + position;
                Toast.makeText(getApplicationContext(), "Selected Item: " + selectedItem, Toast.LENGTH_SHORT).show();
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.items_view, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

activity_items_view.xml(ItemsView - 布局):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.nubage.minepedia.ItemsView">

    <GridView
        android:id="@+id/gridViewCustom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="4dp"
        android:columnWidth="80dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth" />

</RelativeLayout>

item_layout.xml(一个简单条目的布局,应该在GridView中从“activity_items_view.xml”多次出现:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ic_launcher" >
    </ImageView>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textSize="15sp" >
    </TextView>
</LinearLayout>

堆栈跟踪:

08-16 09:42:50.128      914-914/com.nubage.minepedia E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.nubage.minepedia, PID: 914
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nubage.minepedia/com.nubage.minepedia.ItemsView}: java.lang.IllegalArgumentException: column '_id' does not exist
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317)
            at android.app.ActivityThread.access$800(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5070)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
     Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
            at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
            at android.widget.CursorAdapter.init(CursorAdapter.java:172)
            at android.widget.CursorAdapter.<init>(CursorAdapter.java:149)
            at com.nubage.minepedia.GridViewCustomAdapter.<init>(GridViewCustomAdapter.java:28)
            at com.nubage.minepedia.ItemsView.onCreate(ItemsView.java:40)
            at android.app.Activity.performCreate(Activity.java:5720)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1102)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2208)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317)
            at android.app.ActivityThread.access$800(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5070)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
PS:我知道我的代码很丑陋。当基本功能有效时,我想做一些改进。

2 个答案:

答案 0 :(得分:2)

_id列需要位于游标中,而不仅仅是在表格中!您需要在select语句中包含该列。

...而且,顺便说一下,你实际上并不需要表中的_id列。大多数SQLite表都有一个名为ROWID的隐式列,它是唯一且整数值的。通过更改查询以包含以下内容,您可以非常简单地使现有代码生效:

SELECT ROWID as _id, ...

答案 1 :(得分:1)

游标不包含名为_id的列; getSpecificItems不会返回此列。