问题
I'm a noob to android. and I am getting an illegal argument exception when working with a SQLite table. The logcat indicated that this was due to my cursor not being closed so i closed all my cursors. Now i am still getting the IllegalArgumentException with no detail message and my logcat isn't showing any error messages just debug and warning messages. Without any error messages to point me in the right direction i don't know how to even begin to fix this issue. Any help is greatly appreciated.
This is the code that i fixed beforehand with the cursor issue:
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "cointype_name";
public static final String KEY_QUANTITY = "cointype_quantity";
public static final String KEY_OUNCES = "cointype_ounces";
public static final String KEY_VALUE = "cointype_value";
private static final String DATABASE_NAME = "PortfolioDatabase";
private static final String DATABASE_TABLE = "cointypeTable";
private static final int DATABASE_VERSION = 1;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_NAME + " TEXT NOT NULL, " +
KEY_QUANTITY + " TEXT NOT NULL, " +
KEY_OUNCES + " TEXT NOT NULL, " +
KEY_VALUE + " TEXT NOT NULL);"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public PortfolioDatabase(Context c){
ourContext = c;
}
public PortfolioDatabase open() throws SQLException{
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close(){
ourHelper.close();
}
public long createEntry(String coin, String quantity, String ounces, String value) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, coin);
cv.put(KEY_QUANTITY, quantity);
cv.put(KEY_OUNCES, ounces);
cv.put(KEY_VALUE, value);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getData() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + /*c.getString(iRow) + " " +*/ c.getString(iName) + " " + c.getString(iQuantity) + " " + c.getString(iOunces) + " " + c.getString(iValue) + "\n";
}
c.close();
return result;
}
public String getCoin() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + /*c.getString(iRow) + " " +*/ c.getString(iName).substring(0, Math.min(18, c.getString(iName).length())) + "\n";
}
c.close();
return result;
}
public String getQty() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + /*c.getString(iRow) + " " +*/ c.getString(iQuantity) + "\n";
}
c.close();
return result;
}
public String getOunces() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + /*c.getString(iRow) + " " +*/ c.getString(iOunces) + "\n";
}
c.close();
return result;
}
public String getValue() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + /*c.getString(iRow) + " " +*/ c.getString(iValue) + "\n";
}
c.close();
return result;
}
public String getSingleValue(String aCoin) throws SQLException{
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_OUNCES, KEY_VALUE};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_NAME + "=" + aCoin, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iQuantity = c.getColumnIndex(KEY_QUANTITY);
int iOunces = c.getColumnIndex(KEY_OUNCES);
int iValue = c.getColumnIndex(KEY_VALUE);
if (c != null){
c.moveToFirst();
result= c.getString(0);
return result;
}
c.close();
return null;
}
/*public String getHotness(long l) throws SQLException{
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_QUANTITY, KEY_VALUE };
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + l, null, null, null, null);
if (c != null){
c.moveToFirst();
String hotness = c.getString(2);
return hotness;
}
c.close();
return null;
}*/
public void updateEntry(String mCoin, String mQuantity, String mOunces, String mValue) throws SQLException{
// TODO Auto-generated method stub
String[] whereArgs = new String[] { mCoin };
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(KEY_NAME, mCoin);
cvUpdate.put(KEY_QUANTITY, mQuantity);
cvUpdate.put(KEY_OUNCES, mOunces);
cvUpdate.put(KEY_VALUE, mValue);
ourDatabase.update(DATABASE_TABLE, cvUpdate, KEY_NAME + "=?", whereArgs);
}
public void changeCurrency(String mCoin, String mValue) throws SQLException{
// TODO Auto-generated method stub
String[] whereArgs = new String[] { mCoin };
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(KEY_NAME, mCoin);
cvUpdate.put(KEY_VALUE, mValue);
ourDatabase.update(DATABASE_TABLE, cvUpdate, KEY_NAME + "=?", whereArgs);
}
public void deleteEntry(String coin) throws SQLException{
String[] whereArgs = new String[] { coin };
ourDatabase.delete(DATABASE_TABLE, KEY_NAME + "=?", whereArgs);
}
public void removeAll()
{
/*// db.delete(String tableName, String whereClause, String[] whereArgs);
// If whereClause is null, it will delete all rows.
SQLiteDatabase db = helper.getWritableDatabase(); // helper is object extends SQLiteOpenHelper
db.delete(DatabaseHelper.TAB_USERS, null, null);
db.delete(DatabaseHelper.TAB_USERS_GROUP, null, null);*/
ourDatabase.delete(DATABASE_TABLE, null, null);
}
}
The code the causes the error.
public void add(){
boolean didItWork = true;
try {
//String name = sqlName.getText().toString();
//String hotness = sqlHotness.getText().toString();
calculateaddentry();
String coin = addcoinselection.getSelectedItem().toString();
String quantity = sqlAddCoin.getText().toString();
String ounces = entryounces;
String value = denomination + newentryvalue;
//PortfolioDatabase entry = new PortfolioDatabase(Portfolio.this);
info.open();
info.createEntry(coin, quantity, ounces, value);
info.close();
info.open();
String data = info.getData();
String ccoin = info.getCoin();
String cqty = info.getQty();
String counces = info.getOunces();
String cvalue = info.getValue();
info.close();
currentcoin.setText(ccoin);
currentqty.setText(cqty);
currentounces.setText(counces);
currentvalue.setText(cvalue);
} catch (Exception e) {
didItWork = false;
String error = e.toString();
Dialog d = new Dialog(this);
d.setTitle("Dang it!");
TextView tv = new TextView(this);
tv.setText(error);
d.setContentView(tv);
d.show();
} finally {
if (didItWork) {
/*Dialog d = new Dialog(this);
d.setTitle("Heck Yea!");
TextView tv = new TextView(this);
tv.setText("Success");
d.setContentView(tv);
d.show();*/
}
}}
回答1:
Try changing the DATABASE_VERSION
value to 2
and increment when you change the table structure, add columns or add tables in the database class.
The change in the DATABASE_VERSION
triggers the call to onUpgrade()
which in your case will drop the table and create a new one. As long as the DATABASE_VERSION
is the same, onUpgrade()
or onCreate()
won't be called therefore the structure won't be affected and therefore not updating the database structure. This could be the reason why you are getting the IllegalArgumentException as it probably can't find a column in the device's database because the column isn't there. This is what the documentation means when it says:
Note: this class assumes monotonically increasing version numbers for upgrades.
http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html
Thus, if you make a simple database, run it, then add a column in the onCreate()
method without changing the database version, the database class methods onCreate()
or the onUpgrade()
won't be called, because as far as it's concerned, the database is the same.
You must remember that an Android local database is persistent. It will stay on your device beyond the app running. Thus the database holds information from one run of the app to another. The database does not reset every time you run the application. This not only includes the data it holds but also the database structure, such as tables and columns.
When you run the code first is that it will check if a database has been created already. This is on the actual device. If it exists it will check if the database version on the device matches the DATABASE_VERSION
in the helper class. If it does, it doesn't do anything. If the DATABASE_VERSION
in the database class is greater than the database version on the device, then the onUpgrade()
method is called and will adjust the database as defined.
回答2:
Make sure you leave no pending transactions and open cursors.
For INSERT, UPDATE, DELETE:
db.beginTransaction();
try{
//INSERT/UPDATE/DELETE statements here
db.setTransactionSuccessful();
}finally {
db.endTransaction();
}
For Cursors:
Cursor c = db.query( // query code
try{
while(c.moveToNext()){
// read data
}
} finally{
c.close();
}
回答3:
Try renaming the database name and table names to all lowercase.
private static final String DATABASE_NAME = "portfolio_database";
private static final String DATABASE_TABLE = "cointype_table";
Has the database worked before?
来源:https://stackoverflow.com/questions/12179114/how-to-do-i-resolve-illegalargumentexception