2011-02-11 79 views
21

每當我啓動我的應用程序時,我的LogCat中出現java.lang.IllegalArgumentException: column '_id' does not exist錯誤。我創建了列'_id',但它仍然拋出此。這是我主要的.java:由於java.lang.IllegalArgumentException引發的應用程序崩潰:列'_id'不存在

package com.gantt.shoppinglist; 

import android.app.Dialog; 
import android.app.ListActivity; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 

public class ShoppingList extends ListActivity { 

    private DataHelper DataHelper; 
    /** Called when the activity is first created. */ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     DataHelper = new DataHelper(this); 

     Cursor c = (Cursor) DataHelper.selectAll(); 
     long id = c.getLong(c.getColumnIndex("_id")); 
     startManagingCursor(c); 

     ListView lv = (ListView) findViewById(android.R.id.list); 

     String[] from = new String[] { com.gantt.shoppinglist.DataHelper.getDatabaseName() }; 
     int[] to = new int[] { android.R.id.text1 }; 

     SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, 
       android.R.layout.simple_list_item_1, c, from, to);  
     lv.setAdapter(adapter); 

     Button button1main = (Button) findViewById(R.id.add); 
     button1main.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
      final Dialog additem = new Dialog(ShoppingList.this); 
      additem.setContentView(R.layout.maindialog); 
      final EditText et = (EditText)additem.findViewById(R.id.edittext); 
      additem.setTitle("Type your item"); 
      additem.setCancelable(true); 
      et.setHint("Type the name of an item..."); 

      Button button = (Button) additem.findViewById(R.id.cancel); 
      button.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        additem.dismiss(); 
       } 
      }); 
      additem.show(); 

      Button ok = (Button) additem.findViewById(R.id.ok); 
      ok.setOnClickListener(new OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        final String text = et.getText().toString(); 
        additem.dismiss(); 
        et.setText(""); 
       } 
      }); 
     } 
     }); 
    } 
} 

這裏是我的DataHelper類:

package com.gantt.shoppinglist; 

import java.util.ArrayList; 
import java.util.List; 

import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.database.sqlite.SQLiteStatement; 
import android.util.Log; 

public class DataHelper { 

     private static final String DATABASE_NAME = "items.db"; 
     private static final int DATABASE_VERSION = 1; 
     private static final String TABLE_NAME = "table1"; 
     public static final String KEY_ROWID = "_id"; 

     private Context context; 
     private SQLiteDatabase db; 

     private SQLiteStatement insertStmt; 
     private static final String INSERT = "insert into " 
      + TABLE_NAME + "(name) values (?)"; 

     public DataHelper(Context context) { 
      this.context = context; 
      OpenHelper openHelper = new OpenHelper(this.context); 
      this.db = openHelper.getWritableDatabase(); 
      this.insertStmt = this.db.compileStatement(INSERT); 
     } 

     public long insert(String name) { 
      this.insertStmt.bindString(1, name); 
      return this.insertStmt.executeInsert(); 
     } 

     public void deleteAll() { 
      this.db.delete(TABLE_NAME, null, null); 
     } 

     public Cursor selectAll() { 
      List<String> list = new ArrayList<String>(); 
      Cursor cursor = this.db.query(TABLE_NAME, new String[] { "name" }, 
      null, null, null, null, "name desc"); 
      if (cursor.moveToFirst()) { 
      do { 
       list.add(cursor.getString(0)); 
      } while (cursor.moveToNext()); 
      } 
      if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
      } 
      return cursor; 
     } 

     public static String getDatabaseName() { 
     return DATABASE_NAME; 
    } 

    private static class OpenHelper extends SQLiteOpenHelper { 

      OpenHelper(Context context) { 
      super(context, getDatabaseName(), null, DATABASE_VERSION); 
      } 

      @Override 
      public void onCreate(SQLiteDatabase db) { 
       db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY, name TEXT"); 

      } 

      @Override 
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      Log.w("Example", "Upgrading database, this will drop tables and recreate."); 
      db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
      onCreate(db); 
      } 
     } 
    } 
+0

你一定要卸載該應用程序,並重新安裝它,這樣你的數據庫有新創建的_id列?或者也許包含在升級方法? – binnyb 2011-02-11 22:57:40

回答

50

我有一個類似的問題 - 我認爲這是不得不「選擇」(或者「選擇爲」)一種叫做_id因爲SimpleCursorAdapter需要它的情況。

documentation

處理內容URI標識

按照慣例,提供商通過 提供訪問在一個表中的單個行接受內容URI與該行的ID值在 URI的末尾。同樣按照慣例,提供者將ID值與表的 _ID列匹配,並根據匹配的行執行請求的訪問。

這個約定有助於訪問 供應商的應用程序的通用設計模式。該應用程序對提供商進行查詢,並使用CursorAdapterListView中顯示 產生的CursorCursorAdapter的定義 要求Cursor中的一列爲_ID

在我的情況,我在我的表中的自動編號列稱爲「OID」所以我改變了我的SELECT命令是(例如)...

SELECT oid as _id, name, number FROM mytable 

此治癒這個問題對我來說。

編輯,顯示更廣泛的代碼......

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.channel_selector); 

    GridView channel_selector_grid = (GridView) findViewById(R.id.channel_grid); 
    sca = getGuideAdapter(); 
    channel_selector_grid.setAdapter(sca); 
} 

public SimpleCursorAdapter getGuideAdapter() { 
    SimpleCursorAdapter adapter = null; 
    SQLiteDatabase db = SQLiteDatabaseHelper.getReadableDatabase(); 
    Cursor cursor = db.rawQuery("SELECT DISTINCT oid as _id, name, number FROM CHAN_TABLE ORDER BY number", null); 
    if (cursor.moveToFirst()) { 
     String[] columnNames = { "name" }; 
     int[] resIds = { R.id.channel_name }; 
     adapter = new SimpleCursorAdapter(this, R.layout.channel_selector_item, cursor, columnNames, resIds); 
    } 
    return adapter; 
} 
+1

同樣,如果使用managedQuery,它必須在String []數組的第二個參數中包含「_id」。 – NoBugs 2012-05-24 16:43:32

1

嗯不知道,如果你剛剛粘貼它錯了,但:

DataHelper = new DataHelper(this); 
Cursor c = (Cursor) DataHelper.selectAll(); 

是錯誤的。您需要將其申報的對象,並調用初始化數據庫對象的方法:

DataHelper dataHelper = new DataHelper(this); 
Cursor c = (Cursor) dataHelper.selectAll(); 

哦,我的壞你剛剛宣佈以大寫字母d的變量名,這是不建議也不標準的Java編碼樣式。

http://java.about.com/od/javasyntax/a/nameconventions.htm

+0

哦!好吧,我會嘗試 – Cg2916 2011-02-11 23:17:08

相關問題