所以我在另一个页面上创建了一个数据库,它正在运行。现在我试图从SQLite数据库中检索数据并在Android应用程序的ListView上显示。
我为它编写了一个代码,但显然每次我尝试查看都会崩溃。请指教
我想以这样的方式运行 注册 - >登录 - >查看空列表视图 - >添加记录 - >查看包含已添加记录的列表视图
更新了崩溃日志:
01-29 20:42:19.971: E/AndroidRuntime(6003): FATAL EXCEPTION: main
01-29 20:42:19.971: E/AndroidRuntime(6003): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.manandhowproject/mdad.project.Medrecord}: java.lang.IllegalArgumentException: column '_id' does not exist
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread.access$600(ActivityThread.java:141)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.os.Handler.dispatchMessage(Handler.java:99)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.os.Looper.loop(Looper.java:137)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread.main(ActivityThread.java:5103)
01-29 20:42:19.971: E/AndroidRuntime(6003): at java.lang.reflect.Method.invokeNative(Native Method)
01-29 20:42:19.971: E/AndroidRuntime(6003): at java.lang.reflect.Method.invoke(Method.java:525)
01-29 20:42:19.971: E/AndroidRuntime(6003): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
01-29 20:42:19.971: E/AndroidRuntime(6003): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-29 20:42:19.971: E/AndroidRuntime(6003): at dalvik.system.NativeStart.main(Native Method)
01-29 20:42:19.971: E/AndroidRuntime(6003): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.widget.CursorAdapter.init(CursorAdapter.java:168)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.widget.CursorAdapter.<init>(CursorAdapter.java:145)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:91)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:104)
01-29 20:42:19.971: E/AndroidRuntime(6003): at mdad.project.Medrecord.onCreate(Medrecord.java:34)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.Activity.performCreate(Activity.java:5133)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-29 20:42:19.971: E/AndroidRuntime(6003): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
01-29 20:42:19.971: E/AndroidRuntime(6003): ... 11 more
MedRecords.java
package mdad.project;
import com.example.manandhowproject.R;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class Medrecord extends Activity {
SQLiteDatabase db;
ListView lvMedRec;
SimpleCursorAdapter adapter;
Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.medrecord);
createDatabase();
Cursor c = null;
c = db.rawQuery("select * from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};
int[] to = new int[]{R.id.etBodyTemp, R.id.etHeartRate, R.id.etBMI};
adapter = new SimpleCursorAdapter(this,R.layout.medrecord,c,from,to,0);
ListView lvMedRec = (ListView)findViewById(R.id.lvMedRec);
lvMedRec.setAdapter(adapter);
Button button = (Button)findViewById(R.id.btnAdd);
button.setOnClickListener(new OnClickListener(){
public void onClick (View V){
Intent msg5 = new Intent(Medrecord.this, Addorupdate.class);
startActivity(msg5);
}
});
Button button2 = (Button)findViewById(R.id.btnUpdate);
button2.setOnClickListener(new OnClickListener(){
public void onClick (View V){
Intent msg6 = new Intent(Medrecord.this, Addorupdate.class);
startActivity(msg6);
}
});
Button button3 = (Button)findViewById(R.id.btnSignOut);
button3.setOnClickListener(new OnClickListener(){
public void onClick (View V){
Toast.makeText(getApplicationContext(), "Log Out Success ! ", Toast.LENGTH_LONG).show();
Intent msg7 = new Intent(Medrecord.this, Login.class);
startActivity(msg7);
}
});
}
protected void createDatabase(){
db = openOrCreateDatabase("MedRec",Context.MODE_PRIVATE,null);
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text;");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.fourth, 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);
}
}
答案 0 :(得分:0)
是的,看起来是SQL语法错误:
Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
它说你没有'_id'列,它可能来自你创建SimpleCursorAdapter的地方:
adapter = new SimpleCursorAdapter(this,R.layout.medrecord,c,from,to,0);
请参阅此问题:Simple Cursor Adapter problem
修复方法是将'_id'列添加到光标中。但是你已经在光标中添加了所有内容('*'),所以它应该在那里吗?
除非您在表中创建了一个名为'recld'的显式主键,这意味着您的表将没有内置的'_id'列。
无论如何,使用'_id'列作为主键。
protected void createDatabase(){
db = openOrCreateDatabase("MedRec",Context.MODE_PRIVATE,null);
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(_id INTEGER PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text);");
}
答案 1 :(得分:0)
您忘了关闭查询。
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text);");
为什么你要使用自动增量?
更新:
此外,您正在尝试使用需要名为“_id”的列的游标。编辑表创建语句。
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(_id INTEGER PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text);");
答案 2 :(得分:0)
游标适配器要求游标有一个名为 _id 的列(您遇到的错误),这应该是所有表的唯一标识符,除非{{ 1}}短语用于表格的创建,有。
此唯一标识符是一个名为 rowid 的特殊常用隐藏列。编码WITHOUT ROWID
或?? INTEGER PRIMARY KEY
为名为??的rowid列创建别名(其中??是有效的列名)。
因此,在提取光标时,您可以使用 ??INTEGER PRIMARAY KEY AUTOINCREMENT
关键字来使用现有表格。例如改变: -
AS
到
<强> c = db.rawQuery("select * from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};
强>
会产生一个包含 _id 列的光标以及 MedRecords 表中的所有其他列。
或者,由于 recld 是您可以使用的rowid的别名: -
<强> c = db.rawQuery("select rowid AS _id,* from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};
强>
同样,您将拥有一个_id列以及所有其他列,包括Cursor中的 recld 列。
表创建SQL似乎也存在问题,因为缺少尾随的右括号,而不是: -
c = db.rawQuery("select recld AS _id,* from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};
你应该: -
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text;");
但是,如果表格已经存在,则更改上述内容不会更改表格(似乎是这种情况)。如果数据可能丢失,那么在运行根据上述更改之前,您应删除应用程序的数据或卸载应用程序。
如果您需要当前拥有的数据,那么请仔细阅读ALTER TABLE,尤其是标题为 制作其他各种表架构更改 的部分
db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text);");
,它不会将列更改为自动生成唯一ID(rowid)。编码AUTOINCREMENT
就是这么做的。 INTEGER PRIMARY KEY
做的是保证唯一id(rowid)将大于上一次生成的id。它通过使用另一个名为sqlite_sequence的表来以额外的成本存储最后使用的唯一标识符。 SQLite文档声明: - AUTOINCREMENT关键字会产生额外的CPU,内存,磁盘空间和磁盘I / O开销,如果不是严格需要,应该避免使用。通常不需要它。