运行时自定义光标适配器错误,非法参数异常
Posted
技术标签:
【中文标题】运行时自定义光标适配器错误,非法参数异常【英文标题】:Custom Cursor Adapter Error When Running, Illegal Argument Exception 【发布时间】:2014-11-10 11:01:26 【问题描述】:我已经用这些更改更新了我的帖子,我插入了“_id”,一切正常
我希望有人可以帮助解决我的问题,因为我对 android 和 java 还很陌生。我创建了一个使用 SQLite 数据库的应用程序,我正在使用自定义光标适配器打印出数据库的一行以及 2 个按钮和一个 editText。我想我的代码是正确的,但是当我尝试运行应用程序时,我得到了一个 IllegalArgumentException,我已经浏览了这个论坛几天了,但我仍然非常卡住。如果有人能指出我的错误并帮助我解决,那就太好了!
这是我的主要活动
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.pinchtapzoom.R;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MyActivity extends Activity
private CustomCursorAdapter customAdapter;
//private com.example.rory.dbtest.DBAdapter databaseHelper;
public ListView list1;
com.example.rory.dbtest.DBAdapter db = new com.example.rory.dbtest.DBAdapter(this);
//CustomCursorAdapter c = new CustomCursorAdapter(this,c);
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
list1 = (ListView)findViewById(R.id.data_list);
db.open();
Button addBtn = (Button)findViewById(R.id.add);
addBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent i = new Intent(MyActivity.this, addassignment.class);
startActivity(i);
);
Button deleteBtn = (Button)findViewById(R.id.delete);
deleteBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent i = new Intent(MyActivity.this, Delete.class);
startActivity(i);
);
Button updateBtn = (Button)findViewById(R.id.update);
updateBtn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent i = new Intent(MyActivity.this, Update.class);
startActivity(i);
);
try
String destPath = "/data/data/" + getPackageName() + "/databases/AssignmentDB";
File f = new File(destPath);
if (!f.exists())
CopyDB( getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath));
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
new Handler().post(new Runnable()
@Override
public void run()
//Log.d("test", "customadapter is " + customAdapter.toString());
//Log.d("test", "databaseHelper is " + databaseHelper.toString());
customAdapter = new CustomCursorAdapter(MyActivity.this, db.getAllRecords());
list1.setAdapter(customAdapter);
);
private class DBAdapter extends BaseAdapter
private LayoutInflater mInflater;
//private ArrayList<>
@Override
public int getCount()
return 0;
@Override
public Object getItem(int arg0)
return null;
@Override
public long getItemId(int arg0)
return 0;
@Override
public View getView(int arg0, View arg1, ViewGroup arg2)
return null;
public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0)
outputStream.write(buffer, 0, length);
inputStream.close();
outputStream.close();
这是我的数据库类
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
public static final String KEY_ROWID = "_id";
public static final String KEY_ITEM = "item";
public static final String KEY_LITRES = "litres";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "DripDrop";
private static final String DATABASE_TABLE = "assignments";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table if not exists assignments (_id integer primary key autoincrement, "
+ "item VARCHAR not null, litres date );";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
this.context = ctx;
DBHelper = new DatabaseHelper(context);
private static class DatabaseHelper extends SQLiteOpenHelper
DatabaseHelper(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
@Override
public void onCreate(SQLiteDatabase db)
try
db.execSQL(DATABASE_CREATE);
catch (SQLException e)
e.printStackTrace();
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
//---opens the database---
public DBAdapter open() throws SQLException
db = DBHelper.getWritableDatabase();
return this;
//---closes the database---
public void close()
DBHelper.close();
//---insert a record into the database---
public long insertRecord(String item, String litres)
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ITEM, item);
initialValues.put(KEY_LITRES, litres);
return db.insert(DATABASE_TABLE, null, initialValues);
//---deletes a particular record---
public boolean deleteContact(long rowId)
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
//---retrieves all the records---
public Cursor getAllRecords()
return db.query(DATABASE_TABLE, new String[] KEY_ROWID, KEY_ITEM,
KEY_LITRES, null, null,null, null, null);
//---retrieves a particular record---
public Cursor getRecord(long rowId) throws SQLException
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] KEY_ROWID,
KEY_ITEM, KEY_LITRES,
KEY_ROWID + "=" + rowId, null, null, null, null, null);
if (mCursor != null)
mCursor.moveToFirst();
return mCursor;
//---updates a record---
public boolean updateRecord(String item, String litres)
db.execSQL("UPDATE "+DATABASE_TABLE+" SET "+KEY_LITRES+"='"+litres+"' WHERE "+KEY_ITEM+"='"+item+"'");
return true;
这是我的自定义光标类 导入android.content.Context; 导入android.database.Cursor; 导入 android.view.LayoutInflater; 导入android.view.View; 导入android.view.ViewGroup; 导入 android.widget.CursorAdapter; 导入 android.widget.TextView; 导入 com.pinchapzoom.R;
public class CustomCursorAdapter extends CursorAdapter
public CustomCursorAdapter(Context context, Cursor c)
super(context, c);
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
// when the view will be created for first time,
// we need to tell the adapters, how each item will look
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.row, parent, false);
return retView;
@Override
public void bindView(View view, Context context, Cursor cursor)
// here we are setting our data
// that means, take the data from the cursor and put it in views
TextView textViewPersonName = (TextView) view.findViewById(R.id.item1);
textViewPersonName.setText(cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1))));
这是我在运行应用程序时遇到的 logcat 错误
4501-4501/com.example.rory.dbtest E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.rory.dbtest, PID: 4501
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:120)
at com.example.rory.dbtest.CustomCursorAdapter.<init>(CustomCursorAdapter.java:19)
at com.example.rory.dbtest.MyActivity$4.run(MyActivity.java:94)
【问题讨论】:
列名“_id”是预期的,并且“id”表具有,将创建表查询更改为具有“_id” 非常感谢您的回复,我会尝试一下 【参考方案1】:CursorAdapter 总是需要一个名为 _id
的列,您必须为您的 CursoAdapter 提供它,将您的表列 ID 更改为 _id
或者当您从表中查询时,将您的 id
列的别名设置为 @987654324 @
【讨论】:
所以我需要将数据库中的列名从“id”更改为“_id”? 或者你可以从你的 id 列中创建一个别名【参考方案2】:正如 Lukasz 指出的,更改定义为让 id
成为 _id
:
public static final String KEY_ROWID = "_id";
和
private static final String DATABASE_CREATE =
"create table if not exists assignments (_id integer primary key autoincrement, "
+ "item VARCHAR not null, litres date );";
【讨论】:
我尝试运行您所做的更改,但仍然无效,它说没有这样的列?【参考方案3】:基本上,您需要做的是将 id 列更改为 _id,因为在使用自定义光标适配器时,它需要 _id 列。使用带有自定义光标适配器的数据库是不成文的规则
【讨论】:
以上是关于运行时自定义光标适配器错误,非法参数异常的主要内容,如果未能解决你的问题,请参考以下文章