I want to make a listview of some details,it needs to print out the details that are entered.error:Couldn't read row 0, col -1 from CursorWindow

I want to make a listview of some details,it needs to print out the details that are entered.error:Couldn't read row 0, col -1 from CursorWindow

原因:java.lang.IllegalStateException:无法从 CursorWindow 读取第 0 行,第 -1 列。在从游标访问数据之前,确保游标已正确初始化。
我在 android 清单中将 android:allowBackup="true" 更改为 "False"。

public class ListViewActivity extends Activity {
    SQLiteHelper SQLITEHELPER;
    SQLiteDatabase SQLITEDATABASE;
    Cursor cursor;
    SQLiteListAdapter ListAdapter;

    ArrayList<String> CODE_ArrayList = new ArrayList<String>();
    ArrayList<String> ITEM_ArrayList = new ArrayList<String>();
    ArrayList<String> QUANTITY_ArrayList = new ArrayList<String>();
    ArrayList<String> TAX_ArrayList = new ArrayList<String>();
    ArrayList<String> UNITPRICE_ArrayList = new ArrayList<String>();
    ArrayList<String> TOTALPRICE_ArrayList = new ArrayList<String>();
    ArrayList<String> SELLER_ArrayList = new ArrayList<String>();
    ListView LISTVIEW;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_view);    
        LISTVIEW = (ListView)findViewById(R.id.listView1);
        SQLITEHELPER = new SQLiteHelper(this);
    }

    @Override
    protected void onResume() {    
        ShowSQLiteDBdata();
        super.onResume();
    }

    private void ShowSQLiteDBdata() {    
        SQLITEDATABASE = SQLITEHELPER.getWritableDatabase();
        cursor = SQLITEDATABASE.rawQuery("SELECT * FROM demoTableb", null);
        CODE_ArrayList.clear();
        ITEM_ArrayList.clear();
        QUANTITY_ArrayList.clear();
        TAX_ArrayList.clear();
        UNITPRICE_ArrayList.clear();
        TOTALPRICE_ArrayList.clear();
        SELLER_ArrayList.clear();

        if (cursor.moveToFirst()) {
            do {
                CODE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Codes)));
                ITEM_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Item)));
                QUANTITY_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Quantity)));
                TAX_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Tax)));
                UNITPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Unitprice)));
                TOTALPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Totalprice)));
                SELLER_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Seller)));    
            } while (cursor.moveToNext());
        }

        ListAdapter = new SQLiteListAdapter(ListViewActivity.this, 
                CODE_ArrayList,
                ITEM_ArrayList,
                QUANTITY_ArrayList,
                TAX_ArrayList,
                UNITPRICE_ArrayList,
                TOTALPRICE_ArrayList,
                SELLER_ArrayList
                );   
        LISTVIEW.setAdapter(ListAdapter);    
        cursor.close();
    }
}

这是 EditDataActivity

public class EditDataActivity extends Activity {
    Button next, previous, update, delete;    
    EditText item,quantity,tax,unitprice,totalprice,seller;
    SQLiteDatabase SQLITEDATABASE, SQLITEDATABASE2;
    String GetSQliteQuery, UpdateRecordQuery, DeleteQuery ;
    Cursor cursor, cursorCheckDataIsEmptyOrNot ;
    TextView purchase;
    Boolean CheckEditTextEmpty;
    String Item,Quantity,Tax,Unitprice,Totalprice,Seller;
    int ItemCode ;
    String ConvertCode ;
    SQLiteHelper SQLITEHELPER;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_data);

        next = (Button)findViewById(R.id.button1);
        previous = (Button)findViewById(R.id.button2);
        update = (Button)findViewById(R.id.button3);
        delete = (Button)findViewById(R.id.button4);
        item = (EditText)findViewById(R.id.editText2);
        quantity = (EditText)findViewById(R.id.editText3);
        tax = (EditText)findViewById(R.id.editText4);
        unitprice = (EditText)findViewById(R.id.editText5);
        totalprice = (EditText)findViewById(R.id.editText6);
        seller = (EditText)findViewById(R.id.editText7);
        purchase = (TextView)findViewById(R.id.textview1);
        GetSQliteQuery = "SELECT * FROM demoTableb" ;

        SQLITEDATABASE = openOrCreateDatabase("DemoDataBaseb", Context.MODE_PRIVATE, null);
        cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
        cursor.moveToFirst();
        GetSQLiteDatabaseRecords();
        next.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (!cursor.isLast()){
                    cursor.moveToNext();
                }
                GetSQLiteDatabaseRecords();
            }
        });
        previous.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (!cursor.isFirst()){
                    cursor.moveToPrevious();
                }
                GetSQLiteDatabaseRecords();
            }
        });
        update.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Item = item.getText().toString();
                Quantity = quantity.getText().toString();
                Tax = tax.getText().toString();
                Unitprice = unitprice.getText().toString();
                Totalprice = totalprice.getText().toString();
                Seller = seller.getText().toString();
                ConvertCode = purchase.getText().toString();
                ItemCode = Integer.parseInt(ConvertCode);
                UpdateRecordQuery = "UPDATE demoTableb SET  Item ='" + Item + "', Quantity ='" + Quantity + "' ,Tax = '"+Tax+"',Unitprice = '"+Unitprice+"',Totalprice = '"+Totalprice+"',Seller ='"+Seller+"' WHERE Code=" + ItemCode + ";";
                CheckEditTextIsEmptyOrNot(Item,Quantity,Tax,Unitprice,Totalprice,Seller ); 
                if (CheckEditTextEmpty == false) {
                    SQLITEDATABASE.execSQL(UpdateRecordQuery);
                    cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
                    cursor.moveToPosition(ItemCode);
                    Toast.makeText(EditDataActivity.this,"Data Updated Successfully", Toast.LENGTH_LONG).show();
                }else {
                    Toast.makeText(EditDataActivity.this,"Please Fill All the Fields", Toast.LENGTH_LONG).show();
                }
            }
        });

        delete.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                ConvertCode = purchase.getText().toString();
                ItemCode = Integer.parseInt(ConvertCode);
                DeleteQuery = "DELETE FROM demoTableb WHERE Code=" + ItemCode + ";";
                SQLITEDATABASE.execSQL(DeleteQuery);
                Toast.makeText(EditDataActivity.this, "Record Deleted Successfully", Toast.LENGTH_LONG).show();
                cursor = SQLITEDATABASE.rawQuery(GetSQliteQuery, null);
            }
        });
    }

    public void GetSQLiteDatabaseRecords(){
        purchase.setText(cursor.getString(0).toString());
        item.setText(cursor.getString(1).toString());
        quantity.setText(cursor.getString(2).toString());
        tax.setText(cursor.getString(3).toString());
        unitprice.setText(cursor.getString(4).toString());
        totalprice.setText(cursor.getString(5).toString());
        seller.setText(cursor.getString(6).toString());
    }

    public void CheckEditTextIsEmptyOrNot (String Item, String Quantity, String Tax, String Unitprice, String Totalprice,String Seller){
        if( TextUtils.isEmpty(Item) || TextUtils.isEmpty(Quantity)|| TextUtils.isEmpty(Tax)|| TextUtils.isEmpty(Unitprice)|| TextUtils.isEmpty(Totalprice) || TextUtils.isEmpty(Seller)){

            CheckEditTextEmpty = true ;
        }
        else {
            CheckEditTextEmpty = false ;
        }
    }
}

这是主要活动

public class SecondActivity extends Activity {
    EditText code,item,quantity,tax,unitprice,totalprice,seller ;
    Button Submit, EditData, DisplayData;
    SQLiteDatabase SQLITEDATABASE;
    String Codes,Item,Quantity,Tax,Unitprice,Totalprice,Seller ;
    Boolean CheckEditTextEmpty ;
    String SQLiteQuery ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.purchase);
        code = (EditText)findViewById(R.id.edtcd);
        item = (EditText)findViewById(R.id.edtitm);
        quantity= (EditText)findViewById(R.id.edtqty);
        tax = (EditText) findViewById(R.id.edttax);
        unitprice = (EditText) findViewById(R.id.edtprc);
        totalprice = (EditText) findViewById(R.id.edttp);
        seller = (EditText) findViewById(R.id.edtslr);
        Submit = (Button)findViewById(R.id.sbt);
        EditData = (Button)findViewById(R.id.edt);
        DisplayData = (Button)findViewById(R.id.dply);
        Submit.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                DBCreate();
                SubmitData2SQLiteDB();
            }
        });

        EditData.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent i=new Intent(getApplicationContext(),EditDataActivity.class);
                startActivity(i);
            }
        });
        DisplayData.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent i=new Intent(SecondActivity.this,ListViewActivity.class);
                startActivity(i);
            }
        });
    }

    public void DBCreate(){
        SQLITEDATABASE = openOrCreateDatabase("DemoDataBaseb", Context.MODE_PRIVATE, null);
        SQLITEDATABASE.execSQL("CREATE TABLE IF NOT EXISTS demoTableb(Code INTEGER PRIMARY KEY , item INTEGER,quantity  INTEGER, tax INTEGER,Unitprice INTEGER,Totalprice INTEGER,Seller VARCHAR);");
    }

    public void SubmitData2SQLiteDB(){
        Codes = code.getText().toString();
        Item = item.getText().toString();
        Quantity = quantity.getText().toString();
        Tax = tax.getText().toString();
        Unitprice = unitprice.getText().toString();
        Totalprice = totalprice.getText().toString();
        Seller = seller.getText().toString();
        CheckEditTextIsEmptyOrNot( Codes,Item,Quantity,Tax,Unitprice,Totalprice,Seller);
        if(CheckEditTextEmpty == true)
        {
            SQLiteQuery = "INSERT INTO demoTableb (code,item,quantity,tax,unitprice,totalprice,seller) VALUES('"+Codes+"', '"+Item+"','"+Quantity+"','"+Tax+"','"+Unitprice+"','"+Totalprice+"', '"+Seller+"');";
            SQLITEDATABASE.execSQL(SQLiteQuery);
            Toast.makeText(SecondActivity.this,"Data Submit Successfully", Toast.LENGTH_LONG).show();
            ClearEditTextAfterDoneTask();
        }
        else {
            Toast.makeText(SecondActivity.this,"Please Fill All the Fields", Toast.LENGTH_LONG).show();
        }
    }

    public void CheckEditTextIsEmptyOrNot(String code, String item, String quantity, String tax, String Name, String PhoneNumber, String subject){

        if(TextUtils.isEmpty(Codes)  || TextUtils.isEmpty(Item) || TextUtils.isEmpty(Quantity) || TextUtils.isEmpty(Tax) || TextUtils.isEmpty(Unitprice) || TextUtils.isEmpty(Totalprice) || TextUtils.isEmpty(Seller)){
            CheckEditTextEmpty = false ;
        }
        else {
            CheckEditTextEmpty = true ;
        }
    }

    public void ClearEditTextAfterDoneTask(){

        code.getText().clear();
        item.getText().clear();
        quantity.getText().clear();
        tax.getText().clear();
        unitprice.getText().clear();
        totalprice.getText().clear();
        seller.getText().clear();
    }
}
public class SQLiteHelper extends SQLiteOpenHelper {
    static String DATABASE_NAME="DemoDataBaseb";
    public static final String Codes="code";
    public static final String TABLE_NAME="demoTableb";
    public static final String Item="itm";
    public static final String Quantity="qty";
    public static final String Tax="tax";
    public static final String Unitprice="prc";
    public static final String Totalprice="tp";
    public static final String Seller="slr";
    public SQLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, 1); 
    }

    @Override
    public void onCreate(SQLiteDatabase database) {

        String CREATE_TABLE="CREATE TABLE IF NOT EXISTS "+TABLE_NAME+" ("+Codes+" INTEGER PRIMARY KEY, "+Item+" VARCHAR, "+Quantity+" INTEGER, "+Tax+" INTEGER,"+Unitprice+" INTEGER,"+Totalprice+" INTEGER,"+Seller+" VARCHAR )";
        database.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
        onCreate(db);
    }   
}

额外错误

public class MainActivity 扩展 AppCompatActivity {

SuggestedSQLiteHelper dbHelper;
Cursor cursor;
SimpleCursorAdapter sca;
ListView listview1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    dbHelper = new SuggestedSQLiteHelper(this);
    listview1 = this.findViewById(R.id.listView1);
    if (dbHelper.isTableEmpty(SuggestedSQLiteHelper.TABLE_NAME)) {
        dbHelper.insertDemoTablebRow("Item1",1,5,100,100,"Fred");
    }
    setOrRefreshListView();
}

private void setOrRefreshListView() {
    cursor = dbHelper.getAllFromDemoTableb();
    if (sca == null) {
        // setup the adapter
        // NOTE CURSOR ADAPTERS MUST HAVE _ID column which MUST be type INTEGER and UNIQUE
        // see use of BaseColumns._ID in table create
        sca = new SimpleCursorAdapter(this,R.layout.demotableb_layout,cursor,
                // The columns FROM which the data is to be retrieved
                new String[]{
                        SuggestedSQLiteHelper.ITEM_COLUMN,
                        SuggestedSQLiteHelper.QUANTITY_COLUMN,
                        SuggestedSQLiteHelper.TAX_COLUMN,
                        SuggestedSQLiteHelper.UNITPRICE_COLUMN,
                        SuggestedSQLiteHelper.TOTALPRICE_COLUMN,
                        SuggestedSQLiteHelper.SELLER_COLUMN
                },
                // The id of the view's to display the data as per the layout (2nd parm)
                new int[]{
                        R.id.item,
                        R.id.quantity,
                        R.id.tax,
                        R.id.unitprice,
                        R.id.totalprice,
                        R.id.seller
                },0 // 0 is fine
        );
        listview1.setAdapter(sca); // Tie the adapter to the ListView
        // Can add the Listeners here e.g.
        listview1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                // DO SOMETHING HERE NOTING
                // long l passed (4th parm) is the _id of the clicked item
                // hence l can be passed/used as it uniquely identifies the row
                // e.g.
                Cursor csr = dbHelper.getDemotablebById(l);
                DatabaseUtils.dumpCursor(csr);
                csr.close();
            }
        });
    } else {
        sca.swapCursor(cursor);
    }
}

@Override
protected void onResume() {
    super.onResume();
    setOrRefreshListView(); //<<<<<<<<<< will refresh the listview in case data has changed
}

@Override
protected void onDestroy() {
    cursor.close(); //<<<<<<<<< should always close the cursor when done with it
    super.onDestroy();
}

}

错误

原因:java.lang.NullPointerException:尝试在空对象引用上调用虚方法 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' 在 com.allmycode.stac.MainActivity.setOrRefreshListView(MainActivity.java:69) 在 com.allmycode.stac.MainActivity.onCreate(MainActivity.java:40)

问题是 getColumnIndex 方法,如果传递了游标中不存在的列名 returns - 1 根据 :-

Returns the zero-based index for the given column name, or -1 if the column doesn't exist. If you expect the column to exist use getColumnIndexOrThrow(java.lang.String) instead, which will make the error more clear. https://developer.android.com/reference/android/database/Cursor#getColumnIndex(java.lang.String)

因为 Cursor 中不存在这样一个预期的列,并且当您使用 SELECT * .... 时,该列不存在于 table demoTableb.

您需要检查 table 和提取的列是否兼容。那就是将缺失的列添加到 table 或从从游标中提取的列中删除缺失的列。

注意 我相信 getColumnIndex 有一个错误,因为它(曾经)区分大小写(过去肯定是)所以问题可能是列名

如果您不确定,那么转储 Cursor 可能会有所帮助。例如你可以使用:-

cursor = SQLITEDATABASE.rawQuery("SELECT * FROM demoTableb", null);
DatabaseUtils.dumpCursor(cursor); //<<<<<<<<<< Will dump the cursor to the log.

这里有一个被丢弃的 Cursor 的例子:-

09-30 08:25:57.238 1933-1933/so52573525.so52573525 D/ADDRESULT: Added row
09-30 08:25:57.238 1933-1933/so52573525.so52573525 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@456d67
    0 {
       SEM_ID=1
       Date=2018-09-01
       Department=Area 1
       Topic=Blah
       Speaker=Fred
       No_of_Students=10
       Guests=Tom
       Organisation=The org
    }
    1 {
       SEM_ID=2
       Date=2018-08-01
       Department=Area 2
       Topic=Another
       Speaker=Mary
       No_of_Students=100
       Guests=Sue, Tom and Anne
       Organisation=Acme
    }
    <<<<<
  • 从转储中您可以看到 Cursor 中的列是:-

    • SEM_ID
    • 日期
    • 部门
    • 话题
    • 演讲者
    • No_of_Students
    • 来宾
    • 组织
  • 您还可以看到第 0 行和第 1 行已被提取。


附加 评论:-

i uninstalled and reinstalled it but listview doesn't display.i uploaded th SQLiteHelper above could you pls correct it.

我相信卸载和重新安装可以让您继续前进,也就是说您似乎更改了 table 以添加一列,然后 col -1 被固定为 table 随后被更改,因此该列现在存在。

当然,您的代码的本质是有效的。为了证明它确实有效,我使用您的 SQLiteHelper class 组装了一个测试应用程序,没有任何更改,然后从您的 ListViewActivity 并根据 :-

将其放入 activity (MainActivity)
public class MainActivity extends AppCompatActivity {

    SQLiteHelper SQLITEHELPER;
    SQLiteDatabase SQLITEDATABASE;
    Cursor cursor;
    //SQLiteListAdapter ListAdapter;

    ArrayList<String> CODE_ArrayList = new ArrayList<String>();
    ArrayList<String> ITEM_ArrayList = new ArrayList<String>();
    ArrayList<String> QUANTITY_ArrayList = new ArrayList<String>();
    ArrayList<String> TAX_ArrayList = new ArrayList<String>();
    ArrayList<String> UNITPRICE_ArrayList = new ArrayList<String>();
    ArrayList<String> TOTALPRICE_ArrayList = new ArrayList<String>();
    ArrayList<String> SELLER_ArrayList = new ArrayList<String>();
    ListView LISTVIEW;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SQLITEHELPER = new SQLiteHelper(this);
        SQLITEDATABASE = SQLITEHELPER.getWritableDatabase();
        /* ADDED to insert a row ino the table */
        ContentValues cv = new ContentValues();
        cv.put(SQLiteHelper.Item,"Item1");
        cv.put(SQLiteHelper.Quantity,"1");
        cv.put(SQLiteHelper.Seller,"Seller1");
        cv.put(SQLiteHelper.Tax,"X");
        cv.put(SQLiteHelper.Totalprice,"100");
        cv.put(SQLiteHelper.Unitprice,"100");
        SQLITEDATABASE.insert(SQLiteHelper.TABLE_NAME,null,cv);
        ShowSQLiteDBdata();
    }

    private void ShowSQLiteDBdata() {
        SQLITEDATABASE = SQLITEHELPER.getWritableDatabase();

        /*>>>>>>>>>> ADDED to display the schema (tables)*/
        cursor = SQLITEDATABASE.rawQuery("SELECT * FROM sqlite_master;",null);
        DatabaseUtils.dumpCursor(cursor);
        cursor = SQLITEDATABASE.rawQuery("SELECT * FROM demoTableb", null);
        /*>>>>>>>>>> ADDED to dump the cursor from your code */
        DatabaseUtils.dumpCursor(cursor);

        CODE_ArrayList.clear();
        ITEM_ArrayList.clear();
        QUANTITY_ArrayList.clear();
        TAX_ArrayList.clear();
        UNITPRICE_ArrayList.clear();
        TOTALPRICE_ArrayList.clear();
        SELLER_ArrayList.clear();

        if (cursor.moveToFirst()) {
            do {
                CODE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Codes)));
                ITEM_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Item)));
                QUANTITY_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Quantity)));
                TAX_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Tax)));
                UNITPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Unitprice)));
                TOTALPRICE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Totalprice)));
                SELLER_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.Seller)));
            } while (cursor.moveToNext());
        }

        /*>>>>>>>>>> commented out as the SQLiteAdapter class is not available
        ListAdapter = new SQLiteListAdapter(ListViewActivity.this,
                CODE_ArrayList,
                ITEM_ArrayList,
                QUANTITY_ArrayList,
                TAX_ArrayList,
                UNITPRICE_ArrayList,
                TOTALPRICE_ArrayList,
                SELLER_ArrayList
        );
        LISTVIEW.setAdapter(ListAdapter);

         */
        cursor.close();
    }
}

结果

以上为运行时,App没有崩溃,日志包括:-

I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@b9ccda0
I/System.out: 0 {
I/System.out:    type=table
I/System.out:    name=android_metadata
I/System.out:    tbl_name=android_metadata
I/System.out:    rootpage=3
I/System.out:    sql=CREATE TABLE android_metadata (locale TEXT)
I/System.out: }
I/System.out: 1 {
I/System.out:    type=table
I/System.out:    name=demoTableb
I/System.out:    tbl_name=demoTableb
I/System.out:    rootpage=4
I/System.out:    sql=CREATE TABLE demoTableb (code INTEGER PRIMARY KEY, itm VARCHAR, qty INTEGER, tax INTEGER,prc INTEGER,tp INTEGER,slr VARCHAR )
I/System.out: }
I/System.out: <<<<<
  • 模式转储(即 sqlite_master 的内容)

  • 这证实了用于创建 table

    的 demoTableb table 和 SQL 的存在
    • android_metadata 是通过 SQLiteOpenHelper class 生成的 table 并包含语言环境

还包括您的查询根据 :-

生成的 Cursor 的转储
I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@22a7d59
I/System.out: 0 {
I/System.out:    code=1
I/System.out:    itm=Item1
I/System.out:    qty=1
I/System.out:    tax=X
I/System.out:    prc=100
I/System.out:    tp=100
I/System.out:    slr=Seller1
I/System.out: }
I/System.out: <<<<<

使用 Database Inspector(现在是 App Inspection)进一步确认一切都符合预期:-

最后在行 cursor.close(); 上放置一个断点允许检查来自调试 window 的填充数组,例如:-

  • 请注意,数组的大小是 2 而不是 1,因为上面是 运行 第二次和第二行(与第一次相同的数据,但代码列是自动生成,因为它是使用 INTEGER PRIMARY KEY 定义的,没有提供任何值)

因此您原来的问题已经解决,可能是通过卸载并重新安装应用程序,因为 table 可能已更改。


正在进行的问题

如果您遇到持续的问题(ListView 什么都不显示),那应该是 另一个问题,如果是这样,这在很大程度上取决于 SQLiteListAdapter class.


额外

这是一个带有 ListView 的作品 example/demo,更符合我将如何做你正在做的事情。

它没有尝试将游标转换为多个数组然后使用 ListAdapter,而是使用 CursorAdpater (SimpleCursorAdapater)。这些设计用于处理 Cursors 中的数据,因此更简单。

HOWEVER,游标适配器需要一个名为 _id 的列,因此代码列名称已相应更改(它可以保留为是和提取为 _id 的别名)。

访问数据库的代码,例如获取光标的查询已移至助手。

该演示仅插入一行,但包含一个 onItemClickListener,它从数据库中获取被点击的行(您通常不会这样做,但它显示了传递单个值 id 可以在另一个中使用是多么简单activity).

从允许所有相关数据的布局开始(从用户的角度来看)所以 demotableb_layout :-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/item"
        android:layout_width="0dp"
        android:layout_weight="30"
        android:layout_height="match_parent">
    </TextView>
    <TextView
        android:id="@+id/quantity"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="match_parent">
    </TextView>
    <TextView
        android:id="@+id/tax"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="match_parent">
    </TextView>
    <TextView
        android:id="@+id/unitprice"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="match_parent">
    </TextView>
    <TextView
        android:id="@+id/totalprice"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="match_parent">
    </TextView>
    <TextView
        android:id="@+id/seller"
        android:layout_width="0dp"
        android:layout_weight="10"
        android:layout_height="match_parent">
    </TextView>
</LinearLayout>
  • 这显然会更复杂,如果您有这样的布局,那么可以通过对代码进行一些更改(在适配器设置中查看 ID)来使用它

数据库助手建议SQLiteHelper :-

class SuggestedSQLiteHelper extends SQLiteOpenHelper {
    static String DATABASE_NAME="DemoDataBaseb";
    public static final String TABLE_NAME="demoTableb";
    /* column name constant names changed to upper case and more descriptive */
    public static final String CODES_COLUMN = BaseColumns._ID; //<<<<<<<<<< renamed for Cursor Adapter
    public static final String ITEM_COLUMN ="itm";
    public static final String QUANTITY_COLUMN ="qty";
    public static final String TAX_COLUMN="tax";
    public static final String UNITPRICE_COLUMN ="prc";
    public static final String TOTALPRICE_COLUMN ="tp";
    public static final String SELLER_COLUMN ="slr";

    private SQLiteDatabase db; //<<<<<<<<<< Added

    public SuggestedSQLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
        db = this.getWritableDatabase(); //<<<<<<<<<< ADDED to instantiate db
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        String CREATE_TABLE="CREATE TABLE IF NOT EXISTS "+TABLE_NAME+" " +
                "("+
                CODES_COLUMN +" INTEGER PRIMARY KEY, "+
                ITEM_COLUMN +" VARCHAR, "+
                QUANTITY_COLUMN +" INTEGER, "+
                TAX_COLUMN+" INTEGER,"+
                UNITPRICE_COLUMN +" INTEGER,"+
                TOTALPRICE_COLUMN +" INTEGER,"+
                SELLER_COLUMN +" VARCHAR )";
        database.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
        onCreate(db);
    }

    public long insertDemoTablebRow(String item, int quantity, int tax, int unitPrice, int totalPrice, String seller) {
        ContentValues cv = new ContentValues();
        cv.put(ITEM_COLUMN,item);
        cv.put(QUANTITY_COLUMN,quantity);
        cv.put(TAX_COLUMN,tax);
        cv.put(UNITPRICE_COLUMN,unitPrice);
        cv.put(TOTALPRICE_COLUMN,totalPrice);
        cv.put(SELLER_COLUMN,seller);
        return db.insert(TABLE_NAME,null,cv);
    }

    public boolean isTableEmpty(String tableName) {
        return DatabaseUtils.queryNumEntries(db,TABLE_NAME) < 1;
    }

    public Cursor getAllFromDemoTableb() {
        return db.query(TABLE_NAME, null,null,null,null,null,null);
    }

    public Cursor getDemotablebById(long code) {
        return db.query(TABLE_NAME,null,CODES_COLUMN+"=?",new String[]{String.valueOf(code)},null,null,null);
    }
}
  • 注意使用了insert和query的便捷方法,这些给你写底层SQL。它们还绑定数据,从而防止 SQL 注入。

  • 请注意评论

最后将它们放在一个 activity 中(相当于您的 ListViewActivity)是 MainActivity :-

public class MainActivity extends AppCompatActivity {

    SuggestedSQLiteHelper dbHelper;
    Cursor cursor;
    SimpleCursorAdapter sca;
    ListView listview1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new SuggestedSQLiteHelper(this);
        listview1 = this.findViewById(R.id.listview1);
        if (dbHelper.isTableEmpty(SuggestedSQLiteHelper.TABLE_NAME)) {
            dbHelper.insertDemoTablebRow("Item1",1,5,100,100,"Fred");
        }
        setOrRefreshListView();
    }

    private void setOrRefreshListView() {
        cursor = dbHelper.getAllFromDemoTableb();
        if (sca == null) {
            // setup the adapter
            // NOTE CURSOR ADAPTERS MUST HAVE _ID column which MUST be type INTEGER and UNIQUE
            // see use of BaseColumns._ID in table create
            sca = new SimpleCursorAdapter(this,R.layout.demotableb_list,cursor,
                    // The columns FROM which the data is to be retrieved
                    new String[]{
                            SuggestedSQLiteHelper.ITEM_COLUMN,
                            SuggestedSQLiteHelper.QUANTITY_COLUMN,
                            SuggestedSQLiteHelper.TAX_COLUMN,
                            SuggestedSQLiteHelper.UNITPRICE_COLUMN,
                            SuggestedSQLiteHelper.TOTALPRICE_COLUMN,
                            SuggestedSQLiteHelper.SELLER_COLUMN
                    },
                    // The id of the view's to display the data as per the layout (2nd parm)
                    new int[]{
                            R.id.item,
                            R.id.quantity,
                            R.id.tax,
                            R.id.unitprice,
                            R.id.totalprice,
                            R.id.seller
                    },0 // 0 is fine
            );
            listview1.setAdapter(sca); // Tie the adapter to the ListView
            // Can add the Listeners here e.g.
            listview1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    // DO SOMETHING HERE NOTING
                    // long l passed (4th parm) is the _id of the clicked item
                    // hence l can be passed/used as it uniquely identifies the row
                    // e.g.
                    Cursor csr = dbHelper.getDemotablebById(l);
                    DatabaseUtils.dumpCursor(csr);
                    csr.close();
                }
            });
        } else {
            sca.swapCursor(cursor);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        setOrRefreshListView(); //<<<<<<<<<< will refresh the listview in case data has changed
    }

    @Override
    protected void onDestroy() {
        cursor.close(); //<<<<<<<<< should always close the cursor when done with it
        super.onDestroy();
    }
}

结果

运行时的演示:-

点击一个项目(只有上面那个),日志包括:-

I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@1e2064
I/System.out: 0 {
I/System.out:    _id=1
I/System.out:    itm=Item1
I/System.out:    qty=1
I/System.out:    tax=5
I/System.out:    prc=100
I/System.out:    tp=100
I/System.out:    slr=Fred
I/System.out: }
I/System.out: <<<<<