【问题标题】:How to retrieve data from SQLite Database and display on ListView for Java Android Application如何从 SQLite 数据库中检索数据并在 ListView for Java Android Application 上显示
【发布时间】:2018-01-30 01:09:28
【问题描述】:

所以我在另一个页面上创建了一个数据库并且它正在工作。现在我正在尝试从 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);
}

}

【问题讨论】:

  • 请添加崩溃日志。
  • @DataDino 您好,已添加崩溃日志

标签: java android sqlite listview


【解决方案1】:

您忘记关闭查询。

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】:

    是的,看起来是 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);");
    }  
    

    【讨论】:

    • 嘿,我尝试更新 createDatabase(),但它仍然崩溃。请指教谢谢
    • 必须是不同的崩溃;发布它。
    • 您好,我已经更新了崩溃日志,请告知谢谢
    【解决方案3】:

    游标适配器要求游标有一个名为 _id 的列(您遇到的错误),这应该是所有表的唯一标识符,除非 @987654324 @词组用于表的创建,有。

    这个唯一标识符是一个特殊的通常隐藏的列,称为 rowid。编码 ?? INTEGER PRIMARY KEY??INTEGER PRIMARAY KEY AUTOINCREMENT 为名为 ?? 的 rowid 列创建别名。 (其中 ?? 是有效的列名)。

    因此,您可以在提取光标时使用 AS 关键字使用现有表。例如改变:-

    c = db.rawQuery("select * from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};

    c = db.rawQuery("select rowid AS _id,* from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};

    将导致游标包含 _id 列和 MedRecords 表中的所有其他列。

    或者,因为 recld 是您可以使用的 rowid 的别名:-

    c = db.rawQuery("select recld AS _id,* from MedRecords",null);String[] from = new String[]{"Bodytemp","HeartRate","BMI"};

    您将再次拥有一个 _id 列以及所有其他列,包括光标中的 recld 列。


    表创建 SQL 似乎也存在问题,因为缺少结尾的右括号,所以不是:-

    db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text;");
    

    你应该有:-

    db.execSQL("CREATE TABLE IF NOT EXISTS MedRecords(recld integer PRIMARY KEY autoincrement, Bodytemp text, HeartRate text, BMI text);"); 
    

    但是,如果表已经存在(似乎是这种情况),则更改上述内容不会更改表。如果数据可能会丢失,那么在运行根据上述所做的更改之前,您应该删除应用程序的数据或卸载应用程序。

    如果需要您当前拥有的数据,请仔细阅读ALTER TABLE,尤其是标题为进行其他类型的表架构更改

    的部分

    注意事项

    • 很少需要编码AUTOINCREMENT,它不会将列更改为自动生成唯一的id(rowid)。编码INTEGER PRIMARY KEY 就是这样做的。 AUTOINCREMENT 所做的是保证唯一 id(rowid) 将大于最后生成的。它通过使用一个名为 sqlite_sequence 的附加表来存储最后使用的唯一标识符,但需要额外付费。 SQLite 文档指出:-

    AUTOINCREMENT 关键字会带来额外的 CPU、内存、磁盘空间和磁盘 I/O 开销,如果不是严格需要,应避免使用。通常不需要。


    更多信息

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多